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