2SUPPORT.ASM (18329B)
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 ; $Header: F:\projects\c&c0\vcs\code\2support.asv 5.0 11 Nov 1996 09:40:36 JOE_BOSTIC $ 17 ;*************************************************************************** 18 ;** 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 ** 19 ;*************************************************************************** 20 ;* * 21 ;* Project Name : Command & Conquer * 22 ;* * 23 ;* File Name : SUPPORT.ASM * 24 ;* * 25 ;* Programmer : Joe L. Bostic * 26 ;* * 27 ;* Start Date : September 23, 1993 * 28 ;* * 29 ;* Last Update : May 10, 1994 [JLB] * 30 ;* * 31 ;*-------------------------------------------------------------------------* 32 ;* Functions: * 33 ;* strtrim -- Remove the trailing white space from a string. * 34 ;* Fat_Put_Pixel -- Draws a fat pixel. * 35 ;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table.* 36 ;* Remove_From_List -- Removes a pointer from a list of pointers. * 37 ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * 38 39 IDEAL 40 P386 41 MODEL USE32 FLAT 42 43 INCLUDE "gbuffer.inc" 44 DISPLAY "Command & Conquer assembly support routines." 45 46 CODESEG 47 48 49 ;*************************************************************************** 50 ;* Fat_Put_Pixel -- Draws a fat pixel. * 51 ;* * 52 ;* Use this routine to draw a "pixel" that is bigger than 1 pixel * 53 ;* across. This routine is faster than drawing a similar small shape * 54 ;* and faster than calling Fill_Rect. * 55 ;* * 56 ;* INPUT: x,y -- Screen coordinates to draw the pixel's upper * 57 ;* left corner. * 58 ;* * 59 ;* color -- The color to render the pixel in. * 60 ;* * 61 ;* size -- The number of pixels width of the big "pixel". * 62 ;* * 63 ;* page -- The pointer to a GraphicBuffer class or something * 64 ;* * 65 ;* OUTPUT: none * 66 ;* * 67 ;* WARNINGS: none * 68 ;* * 69 ;* HISTORY: * 70 ;* 03/17/1994 JLB : Created. * 71 ;*=========================================================================* 72 ; VOID cdecl Fat_Put_Pixel(long x, long y, long color, long size, void *page) 73 GLOBAL C Fat_Put_Pixel:NEAR 74 PROC Fat_Put_Pixel C near 75 USES eax, ebx, ecx, edx, edi, esi 76 77 ARG x:DWORD ; X coordinate of upper left pixel corner. 78 ARG y:DWORD ; Y coordinate of upper left pixel corner. 79 ARG color:DWORD ; Color to use for the "pixel". 80 ARG siz:DWORD ; Size of "pixel" to plot (square). 81 ARG gpage:DWORD ; graphic page address to plot onto 82 83 cmp [siz],0 84 je short ??exit 85 86 ; Set EDI to point to start of logical page memory. 87 ;*=================================================================== 88 ; Get the viewport information and put bytes per row in ecx 89 ;*=================================================================== 90 mov ebx,[gpage] ; get a pointer to viewport 91 mov edi,[(GraphicViewPort ebx).GVPOffset] ; get the correct offset 92 93 ; Verify the the Y pixel offset is legal. 94 mov eax,[y] 95 cmp eax,[(GraphicViewPort ebx).GVPHeight] ;YPIXEL_MAX 96 jae short ??exit 97 mov ecx,[(GraphicViewPort ebx).GVPWidth] 98 add ecx,[(GraphicViewPort ebx).GVPXAdd] 99 add ecx,[(GraphicViewPort ebx).GVPPitch] 100 mul ecx 101 add edi,eax 102 103 ; Verify the the X pixel offset is legal. 104 105 mov edx,[(GraphicViewPort ebx).GVPWidth] 106 cmp edx,[x] 107 mov edx,ecx 108 jbe short ??exit 109 add edi,[x] 110 111 ; Write the pixel to the screen. 112 mov ebx,[siz] ; Copy of pixel size. 113 sub edx,ebx ; Modulo to reach start of next row. 114 mov eax,[color] 115 ??again: 116 mov ecx,ebx 117 rep stosb 118 add edi,edx ; EDI points to start of next row. 119 dec [siz] 120 jnz short ??again 121 122 ??exit: 123 ret 124 125 ENDP Fat_Put_Pixel 126 127 128 if 0 129 130 ;*************************************************************************** 131 ;* strtrim -- Remove the trailing white space from a string. * 132 ;* * 133 ;* Use this routine to remove white space characters from the beginning * 134 ;* and end of the string. The string is modified in place by * 135 ;* this routine. * 136 ;* * 137 ;* INPUT: buffer -- Pointer to the string to modify. * 138 ;* * 139 ;* OUTPUT: none * 140 ;* * 141 ;* WARNINGS: none * 142 ;* * 143 ;* HISTORY: * 144 ;* 10/07/1992 JLB : Created. * 145 ;*=========================================================================* 146 ; VOID cdecl strtrim(BYTE *buffer); 147 GLOBAL C strtrim :NEAR 148 PROC strtrim C near 149 USES ax, edi, esi 150 151 ARG buffer:DWORD ; Pointer to string to modify. 152 153 cmp [buffer],0 154 je short ??fini 155 156 ; Prepare for string scanning by loading pointers. 157 cld 158 mov esi,[buffer] 159 mov edi,esi 160 161 ; Strip white space from the start of the string. 162 ??looper: 163 lodsb 164 cmp al,20h ; Space 165 je short ??looper 166 cmp al,9 ; TAB 167 je short ??looper 168 stosb 169 170 ; Copy the rest of the string. 171 ??gruntloop: 172 lodsb 173 stosb 174 or al,al 175 jnz short ??gruntloop 176 dec edi 177 ; Strip the white space from the end of the string. 178 ??looper2: 179 mov [edi],al 180 dec edi 181 mov ah,[edi] 182 cmp ah,20h 183 je short ??looper2 184 cmp ah,9 185 je short ??looper2 186 187 ??fini: 188 ret 189 190 ENDP strtrim 191 192 193 ;*************************************************************************** 194 ;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table. * 195 ;* * 196 ;* This routine is used to build a special fading table for C&C. There * 197 ;* are certain colors that get faded to and cannot be faded again. * 198 ;* With this rule, it is possible to draw a shadow multiple times and * 199 ;* not have it get any lighter or darker. * 200 ;* * 201 ;* INPUT: palette -- Pointer to the 768 byte IBM palette to build from. * 202 ;* * 203 ;* dest -- Pointer to the 256 byte remap table. * 204 ;* * 205 ;* color -- Color index of the color to "fade to". * 206 ;* * 207 ;* frac -- The fraction to fade to the specified color * 208 ;* * 209 ;* OUTPUT: Returns with pointer to the remap table. * 210 ;* * 211 ;* WARNINGS: none * 212 ;* * 213 ;* HISTORY: * 214 ;* 10/07/1992 JLB : Created. * 215 ;*=========================================================================*/ 216 ;VOID * cdecl Conquer_Build_Fading_Table(VOID *palette, VOID *dest, long color, long frac); 217 GLOBAL C Conquer_Build_Fading_Table : NEAR 218 PROC Conquer_Build_Fading_Table C near 219 USES ebx, ecx, edi, esi 220 221 ARG palette:DWORD 222 ARG dest:DWORD 223 ARG color:DWORD 224 ARG frac:DWORD 225 226 LOCAL matchvalue:DWORD ; Last recorded match value. 227 LOCAL targetred:BYTE ; Target gun red. 228 LOCAL targetgreen:BYTE ; Target gun green. 229 LOCAL targetblue:BYTE ; Target gun blue. 230 LOCAL idealred:BYTE 231 LOCAL idealgreen:BYTE 232 LOCAL idealblue:BYTE 233 LOCAL matchcolor:BYTE ; Tentative match color. 234 235 ALLOWED_COUNT EQU 16 236 ALLOWED_START EQU 256-ALLOWED_COUNT 237 238 cld 239 240 ; If the source palette is NULL, then just return with current fading table pointer. 241 cmp [palette],0 242 je ??fini1 243 cmp [dest],0 244 je ??fini1 245 246 ; Fractions above 255 become 255. 247 mov eax,[frac] 248 cmp eax,0100h 249 jb short ??ok 250 mov [frac],0FFh 251 ??ok: 252 253 ; Record the target gun values. 254 mov esi,[palette] 255 mov ebx,[color] 256 add esi,ebx 257 add esi,ebx 258 add esi,ebx 259 lodsb 260 mov [targetred],al 261 lodsb 262 mov [targetgreen],al 263 lodsb 264 mov [targetblue],al 265 266 ; Main loop. 267 xor ebx,ebx ; Remap table index. 268 269 ; Transparent black never gets remapped. 270 mov edi,[dest] 271 mov [edi],bl 272 inc edi 273 274 ; EBX = source palette logical number (1..255). 275 ; EDI = running pointer into dest remap table. 276 ??mainloop: 277 inc ebx 278 mov esi,[palette] 279 add esi,ebx 280 add esi,ebx 281 add esi,ebx 282 283 mov edx,[frac] 284 shr edx,1 285 ; new = orig - ((orig-target) * fraction); 286 287 lodsb ; orig 288 mov dh,al ; preserve it for later. 289 sub al,[targetred] ; al = (orig-target) 290 imul dl ; ax = (orig-target)*fraction 291 shl eax,1 292 sub dh,ah ; dh = orig - ((orig-target) * fraction) 293 mov [idealred],dh ; preserve ideal color gun value. 294 295 lodsb ; orig 296 mov dh,al ; preserve it for later. 297 sub al,[targetgreen] ; al = (orig-target) 298 imul dl ; ax = (orig-target)*fraction 299 shl eax,1 300 sub dh,ah ; dh = orig - ((orig-target) * fraction) 301 mov [idealgreen],dh ; preserve ideal color gun value. 302 303 lodsb ; orig 304 mov dh,al ; preserve it for later. 305 sub al,[targetblue] ; al = (orig-target) 306 imul dl ; ax = (orig-target)*fraction 307 shl eax,1 308 sub dh,ah ; dh = orig - ((orig-target) * fraction) 309 mov [idealblue],dh ; preserve ideal color gun value. 310 311 ; Sweep through a limited set of existing colors to find the closest 312 ; matching color. 313 314 mov eax,[color] 315 mov [matchcolor],al ; Default color (self). 316 mov [matchvalue],-1 ; Ridiculous match value init. 317 mov ecx,ALLOWED_COUNT 318 319 mov esi,[palette] ; Pointer to original palette. 320 add esi,(ALLOWED_START)*3 321 322 ; BH = color index. 323 mov bh,ALLOWED_START 324 ??innerloop: 325 326 xor edx,edx ; Comparison value starts null. 327 328 ; Build the comparison value based on the sum of the differences of the color 329 ; guns squared. 330 lodsb 331 sub al,[idealred] 332 mov ah,al 333 imul ah 334 add edx,eax 335 336 lodsb 337 sub al,[idealgreen] 338 mov ah,al 339 imul ah 340 add edx,eax 341 342 lodsb 343 sub al,[idealblue] 344 mov ah,al 345 imul ah 346 add edx,eax 347 jz short ??perfect ; If perfect match found then quit early. 348 349 cmp edx,[matchvalue] 350 jae short ??notclose 351 mov [matchvalue],edx ; Record new possible color. 352 mov [matchcolor],bh 353 ??notclose: 354 inc bh ; Checking color index. 355 loop ??innerloop 356 mov bh,[matchcolor] 357 ??perfect: 358 mov [matchcolor],bh 359 xor bh,bh ; Make BX valid main index again. 360 361 ; When the loop exits, we have found the closest match. 362 mov al,[matchcolor] 363 stosb 364 cmp ebx,ALLOWED_START-1 365 jne ??mainloop 366 367 ; Fill the remainder of the remap table with values 368 ; that will remap the color to itself. 369 mov ecx,ALLOWED_COUNT 370 ??fillerloop: 371 inc bl 372 mov al,bl 373 stosb 374 loop ??fillerloop 375 376 ??fini1: 377 mov esi,[dest] 378 mov eax,esi 379 ret 380 381 ENDP Conquer_Build_Fading_Table 382 383 384 ;*************************************************************************** 385 ;* Remove_From_List -- Removes a pointer from a list of pointers. * 386 ;* * 387 ;* This low level routine is used to remove a pointer from a list of * 388 ;* pointers. The trailing pointers are moved downward to fill the * 389 ;* hole. * 390 ;* * 391 ;* INPUT: list -- Pointer to list of pointer. * 392 ;* * 393 ;* index -- Pointer to length of pointer list. * 394 ;* * 395 ;* ptr -- The pointer value to search for and remove. * 396 ;* * 397 ;* OUTPUT: none * 398 ;* * 399 ;* WARNINGS: none * 400 ;* * 401 ;* HISTORY: * 402 ;* 04/11/1994 JLB : Created. * 403 ;* 04/22/1994 JLB : Convert to assembly language. * 404 ;* 05/10/1994 JLB : Short pointers now. * 405 ;*=========================================================================*/ 406 ;VOID cdecl Remove_From_List(VOID **list, long *index, long ptr); 407 GLOBAL C Remove_From_List:NEAR 408 PROC Remove_From_List C near 409 USES edi, esi, ecx, eax 410 ARG list:DWORD ; Pointer to list. 411 ARG index:DWORD ; Pointer to count. 412 ARG element:DWORD ; Element to remove. 413 414 ; Fetch the number of elements in the list. If there are no 415 ; elements, then just exit quickly. 416 mov edi,[index] 417 mov ecx,[edi] 418 jcxz short ??fini2 419 420 ; Fetch pointer to list. 421 cmp [list],0 422 je short ??fini2 423 mov edi,[list] 424 425 ; Loop through all elements searching for a match. 426 mov eax,[element] 427 repne scasd 428 jne short ??fini2 ; No match found. 429 430 ; Copy all remaining elements down. If this is the 431 ; last element in the list then nothing needs to be 432 ; copied -- just decrement the list size. 433 jcxz short ??nocopy ; No copy necessary. 434 mov esi,edi 435 sub edi,4 436 rep movsd 437 438 ; Reduce the list count by one. 439 ??nocopy: 440 mov edi,[index] 441 dec [DWORD PTR edi] 442 443 ??fini2: 444 ret 445 446 ENDP Remove_From_List 447 448 449 ; long cdecl Get_EAX(); 450 GLOBAL C Get_EAX :NEAR 451 PROC Get_EAX C near 452 ret 453 454 ENDP Get_EAX 455 endif 456 457 458 DATASEG 459 460 TabA DD 6949350 461 DD 4913933 462 DD 3474675 463 DD 2456966 464 DD 1737338 465 DD 1228483 466 DD 868669 467 DD 614242 468 DD 434334 469 DD 307121 470 DD 217167 471 DD 153560 472 DD 108584 473 DD 76780 474 DD 54292 475 DD 38390 476 DD 27146 477 DD 19195 478 DD 13573 479 DD 9598 480 DD 6786 481 DD 4799 482 DD 3393 483 DD 2399 484 DD 1697 485 DD 1200 486 DD 848 487 DD 600 488 DD 424 489 DD 300 490 DD 212 491 DD 150 492 DD 106 493 494 TabB DD 154 495 DD 218 496 DD 309 497 DD 437 498 DD 618 499 DD 874 500 DD 1236 501 DD 1748 502 DD 2472 503 DD 3496 504 DD 4944 505 DD 6992 506 DD 9888 507 DD 13983 508 DD 19775 509 DD 27967 510 DD 39551 511 DD 55933 512 DD 79101 513 DD 111866 514 DD 158203 515 DD 223732 516 DD 316405 517 DD 447465 518 DD 632811 519 DD 894929 520 DD 1265621 521 DD 1789859 522 DD 2531243 523 DD 3579718 524 DD 5062486 525 DD 7159436 526 DD 10124971 527 528 CODESEG 529 530 ;*********************************************************************************************** 531 ;* Square_Root -- Finds the square root of the fixed pointer parameter. * 532 ;* * 533 ;* INPUT: val -- The fixed point (16:16) value to find the square root of. * 534 ;* * 535 ;* OUTPUT: Returns with the square root of the fixed pointer parameter. * 536 ;* * 537 ;* WARNINGS: none * 538 ;* * 539 ;* HISTORY: * 540 ;* 10/04/1995 JLB : Adapted. * 541 ;*=============================================================================================*/ 542 ;unsigned Square_Root(unsigned val); 543 GLOBAL C Square_Root :NEAR 544 PROC Square_Root C near 545 USES ebx,edx 546 547 bsr ebx,eax 548 jz ??zero 549 550 mul [DWORD 4*ebx + OFFSET TabA] 551 shrd eax,edx,10h 552 add eax, [4*ebx + OFFSET TabB] 553 ??zero: 554 ret 555 556 ENDP Square_Root 557 558 ;---------------------------------------------------------------------------- 559 560 END 561