SCALE.ASM 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. ;
  2. ; Command & Conquer Red Alert(tm)
  3. ; Copyright 2025 Electronic Arts Inc.
  4. ;
  5. ; This program is free software: you can redistribute it and/or modify
  6. ; it under the terms of the GNU General Public License as published by
  7. ; the Free Software Foundation, either version 3 of the License, or
  8. ; (at your option) any later version.
  9. ;
  10. ; This program is distributed in the hope that it will be useful,
  11. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ; GNU General Public License for more details.
  14. ;
  15. ; You should have received a copy of the GNU General Public License
  16. ; along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. ;
  18. ;***************************************************************************
  19. ;** 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 **
  20. ;***************************************************************************
  21. ;* *
  22. ;* Project Name : Westwood 32 bit Library *
  23. ;* *
  24. ;* File Name : SCALE.ASM *
  25. ;* *
  26. ;* Programmer : Phil W. Gorrow *
  27. ;* *
  28. ;* Start Date : June 16, 1994 *
  29. ;* *
  30. ;* Last Update : June 21, 1994 [PWG] *
  31. ;* New version : feb 12, 1995 [JRJ] *
  32. ;* *
  33. ;*-------------------------------------------------------------------------*
  34. ;* Functions: *
  35. ;* VVC::Scale -- Scales a virtual viewport to another virtual viewport *
  36. ;* Normal_Draw -- jump loc for drawing scaled line of normal pixel *
  37. ;* Normal_Remapped_Draw -- jump loc for draw scaled line of remap pixel *
  38. ;* Transparent_Draw -- jump loc for scaled line of transparent pixels *
  39. ;* Transparent_Remapped_Draw -- jump loc for scaled remap trans pixels *
  40. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  41. IDEAL
  42. P386
  43. MODEL USE32 FLAT
  44. INCLUDE ".\drawbuff.inc"
  45. INCLUDE ".\gbuffer.inc"
  46. CODESEG
  47. ;***************************************************************************
  48. ;* VVC::SCALE -- Scales a virtual viewport to another virtual viewport *
  49. ;* *
  50. ;* INPUT: *
  51. ;* *
  52. ;* OUTPUT: *
  53. ;* *
  54. ;* WARNINGS: *
  55. ;* *
  56. ;* HISTORY: *
  57. ;* 06/16/1994 PWG : Created. *
  58. ;*=========================================================================*
  59. PROC Linear_Scale_To_Linear C NEAR
  60. USES eax,ebx,ecx,edx,esi,edi
  61. ;*===================================================================
  62. ;* Define the arguements that our function takes.
  63. ;*===================================================================
  64. ARG this_object:DWORD ; pointer to source view port
  65. ARG dest:DWORD ; pointer to destination view port
  66. ARG src_x:DWORD ; source x offset into view port
  67. ARG src_y:DWORD ; source y offset into view port
  68. ARG dst_x:DWORD ; dest x offset into view port
  69. ARG dst_y:DWORD ; dest y offset into view port
  70. ARG src_width:DWORD ; width of source rectangle
  71. ARG src_height:DWORD ; height of source rectangle
  72. ARG dst_width:DWORD ; width of dest rectangle
  73. ARG dst_height:DWORD ; width of dest height
  74. ARG trans:DWORD ; is this transparent?
  75. ARG remap:DWORD ; pointer to table to remap source
  76. ;*===================================================================
  77. ;* Define local variables to hold the viewport characteristics
  78. ;*===================================================================
  79. local src_x0 : dword
  80. local src_y0 : dword
  81. local src_x1 : dword
  82. local src_y1 : dword
  83. local dst_x0 : dword
  84. local dst_y0 : dword
  85. local dst_x1 : dword
  86. local dst_y1 : dword
  87. local src_win_width : dword
  88. local dst_win_width : dword
  89. local dy_intr : dword
  90. local dy_frac : dword
  91. local dy_acc : dword
  92. local dx_frac : dword
  93. local counter_x : dword
  94. local counter_y : dword
  95. local remap_counter :dword
  96. local entry : dword
  97. ;*===================================================================
  98. ;* Check for scale error when to or from size 0,0
  99. ;*===================================================================
  100. cmp [dst_width],0
  101. je ??all_done
  102. cmp [dst_height],0
  103. je ??all_done
  104. cmp [src_width],0
  105. je ??all_done
  106. cmp [src_height],0
  107. je ??all_done
  108. mov eax , [ src_x ]
  109. mov ebx , [ src_y ]
  110. mov [ src_x0 ] , eax
  111. mov [ src_y0 ] , ebx
  112. add eax , [ src_width ]
  113. add ebx , [ src_height ]
  114. mov [ src_x1 ] , eax
  115. mov [ src_y1 ] , ebx
  116. mov eax , [ dst_x ]
  117. mov ebx , [ dst_y ]
  118. mov [ dst_x0 ] , eax
  119. mov [ dst_y0 ] , ebx
  120. add eax , [ dst_width ]
  121. add ebx , [ dst_height ]
  122. mov [ dst_x1 ] , eax
  123. mov [ dst_y1 ] , ebx
  124. ; Clip Source Rectangle against source Window boundaries.
  125. mov esi , [ this_object ] ; get ptr to src
  126. xor ecx , ecx
  127. xor edx , edx
  128. mov edi , [ (GraphicViewPort esi) . GVPWidth ] ; get width into register
  129. mov eax , [ src_x0 ]
  130. mov ebx , [ src_x1 ]
  131. shld ecx , eax , 1
  132. inc edi
  133. shld edx , ebx , 1
  134. sub eax , edi
  135. sub ebx , edi
  136. shld ecx , eax , 1
  137. shld edx , ebx , 1
  138. mov edi,[ ( GraphicViewPort esi) . GVPHeight ] ; get height into register
  139. mov eax , [ src_y0 ]
  140. mov ebx , [ src_y1 ]
  141. shld ecx , eax , 1
  142. inc edi
  143. shld edx , ebx , 1
  144. sub eax , edi
  145. sub ebx , edi
  146. shld ecx , eax , 1
  147. shld edx , ebx , 1
  148. xor cl , 5
  149. xor dl , 5
  150. mov al , cl
  151. test dl , cl
  152. jnz ??all_done
  153. or al , dl
  154. jz ??clip_against_dest
  155. mov bl , dl
  156. test cl , 1000b
  157. jz ??src_left_ok
  158. xor eax , eax
  159. mov [ src_x0 ] , eax
  160. sub eax , [ src_x ]
  161. imul [ dst_width ]
  162. idiv [ src_width ]
  163. add eax , [ dst_x ]
  164. mov [ dst_x0 ] , eax
  165. ??src_left_ok:
  166. test cl , 0010b
  167. jz ??src_bottom_ok
  168. xor eax , eax
  169. mov [ src_y0 ] , eax
  170. sub eax , [ src_y ]
  171. imul [ dst_height ]
  172. idiv [ src_height ]
  173. add eax , [ dst_y ]
  174. mov [ dst_y0 ] , eax
  175. ??src_bottom_ok:
  176. test bl , 0100b
  177. jz ??src_right_ok
  178. mov eax , [ (GraphicViewPort esi) . GVPWidth ] ; get width into register
  179. mov [ src_x1 ] , eax
  180. sub eax , [ src_x ]
  181. imul [ dst_width ]
  182. idiv [ src_width ]
  183. add eax , [ dst_x ]
  184. mov [ dst_x1 ] , eax
  185. ??src_right_ok:
  186. test bl , 0001b
  187. jz ??clip_against_dest
  188. mov eax , [ (GraphicViewPort esi) . GVPHeight ] ; get width into register
  189. mov [ src_y1 ] , eax
  190. sub eax , [ src_y ]
  191. imul [ dst_height ]
  192. idiv [ src_height ]
  193. add eax , [ dst_y ]
  194. mov [ dst_y1 ] , eax
  195. ; Clip destination Rectangle against source Window boundaries.
  196. ??clip_against_dest:
  197. mov esi , [ dest ] ; get ptr to src
  198. xor ecx , ecx
  199. xor edx , edx
  200. mov edi , [ (GraphicViewPort esi) . GVPWidth ] ; get width into register
  201. mov eax , [ dst_x0 ]
  202. mov ebx , [ dst_x1 ]
  203. shld ecx , eax , 1
  204. inc edi
  205. shld edx , ebx , 1
  206. sub eax , edi
  207. sub ebx , edi
  208. shld ecx , eax , 1
  209. shld edx , ebx , 1
  210. mov edi,[ ( GraphicViewPort esi) . GVPHeight ] ; get height into register
  211. mov eax , [ dst_y0 ]
  212. mov ebx , [ dst_y1 ]
  213. shld ecx , eax , 1
  214. inc edi
  215. shld edx , ebx , 1
  216. sub eax , edi
  217. sub ebx , edi
  218. shld ecx , eax , 1
  219. shld edx , ebx , 1
  220. xor cl , 5
  221. xor dl , 5
  222. mov al , cl
  223. test dl , cl
  224. jnz ??all_done
  225. or al , dl
  226. jz ??do_scaling
  227. mov bl , dl
  228. test cl , 1000b
  229. jz ??dst_left_ok
  230. xor eax , eax
  231. mov [ dst_x0 ] , eax
  232. sub eax , [ dst_x ]
  233. imul [ src_width ]
  234. idiv [ dst_width ]
  235. add eax , [ src_x ]
  236. mov [ src_x0 ] , eax
  237. ??dst_left_ok:
  238. test cl , 0010b
  239. jz ??dst_bottom_ok
  240. xor eax , eax
  241. mov [ dst_y0 ] , eax
  242. sub eax , [ dst_y ]
  243. imul [ src_height ]
  244. idiv [ dst_height ]
  245. add eax , [ src_y ]
  246. mov [ src_y0 ] , eax
  247. ??dst_bottom_ok:
  248. test bl , 0100b
  249. jz ??dst_right_ok
  250. mov eax , [ (GraphicViewPort esi) . GVPWidth ] ; get width into register
  251. mov [ dst_x1 ] , eax
  252. sub eax , [ dst_x ]
  253. imul [ src_width ]
  254. idiv [ dst_width ]
  255. add eax , [ src_x ]
  256. mov [ src_x1 ] , eax
  257. ??dst_right_ok:
  258. test bl , 0001b
  259. jz ??do_scaling
  260. mov eax , [ (GraphicViewPort esi) . GVPHeight ] ; get width into register
  261. mov [ dst_y1 ] , eax
  262. sub eax , [ dst_y ]
  263. imul [ src_height ]
  264. idiv [ dst_height ]
  265. add eax , [ src_y ]
  266. mov [ src_y1 ] , eax
  267. ??do_scaling:
  268. cld
  269. mov ebx , [ this_object ]
  270. mov esi , [ (GraphicViewPort ebx) . GVPOffset ]
  271. mov eax , [ (GraphicViewPort ebx) . GVPXAdd ]
  272. add eax , [ (GraphicViewPort ebx) . GVPWidth ]
  273. add eax , [ (GraphicViewPort ebx) . GVPPitch ]
  274. mov [ src_win_width ] , eax
  275. mul [ src_y0 ]
  276. add esi , [ src_x0 ]
  277. add esi , eax
  278. mov ebx , [ dest ]
  279. mov edi , [ (GraphicViewPort ebx) . GVPOffset ]
  280. mov eax , [ (GraphicViewPort ebx) . GVPXAdd ]
  281. add eax , [ (GraphicViewPort ebx) . GVPWidth ]
  282. add eax , [ (GraphicViewPort ebx) . GVPPitch ]
  283. mov [ dst_win_width ] , eax
  284. mul [ dst_y0 ]
  285. add edi , [ dst_x0 ]
  286. add edi , eax
  287. mov eax , [ src_height ]
  288. xor edx , edx
  289. mov ebx , [ dst_height ]
  290. idiv [ dst_height ]
  291. imul eax , [ src_win_width ]
  292. neg ebx
  293. mov [ dy_intr ] , eax
  294. mov [ dy_frac ] , edx
  295. mov [ dy_acc ] , ebx
  296. mov eax , [ src_width ]
  297. xor edx , edx
  298. shl eax , 16
  299. idiv [ dst_width ]
  300. xor edx , edx
  301. shld edx , eax , 16
  302. shl eax , 16
  303. mov ecx , [ dst_y1 ]
  304. mov ebx , [ dst_x1 ]
  305. sub ecx , [ dst_y0 ]
  306. jle ??all_done
  307. sub ebx , [ dst_x0 ]
  308. jle ??all_done
  309. mov [ counter_y ] , ecx
  310. cmp [ trans ] , 0
  311. jnz ??transparency
  312. cmp [ remap ] , 0
  313. jnz ??normal_remap
  314. ; *************************************************************************
  315. ; normal scale
  316. mov ecx , ebx
  317. and ecx , 01fh
  318. lea ecx , [ ecx + ecx * 2 ]
  319. shr ebx , 5
  320. neg ecx
  321. mov [ counter_x ] , ebx
  322. lea ecx , [ ??ref_point + ecx + ecx * 2 ]
  323. mov [ entry ] , ecx
  324. ??outter_loop:
  325. push esi
  326. push edi
  327. xor ecx , ecx
  328. mov ebx , [ counter_x ]
  329. jmp [ entry ]
  330. ??inner_loop:
  331. REPT 32
  332. mov cl , [ esi ]
  333. add ecx , eax
  334. adc esi , edx
  335. mov [ edi ] , cl
  336. inc edi
  337. ENDM
  338. ??ref_point:
  339. dec ebx
  340. jge ??inner_loop
  341. pop edi
  342. pop esi
  343. add edi , [ dst_win_width ]
  344. add esi , [ dy_intr ]
  345. mov ebx , [ dy_acc ]
  346. add ebx , [ dy_frac ]
  347. jle ??skip_line
  348. add esi , [ src_win_width ]
  349. sub ebx , [ dst_height ]
  350. ??skip_line:
  351. dec [ counter_y ]
  352. mov [ dy_acc ] , ebx
  353. jnz ??outter_loop
  354. ret
  355. ; *************************************************************************
  356. ; normal scale with remap
  357. ??normal_remap:
  358. mov ecx , ebx
  359. mov [ dx_frac ], eax
  360. and ecx , 01fh
  361. mov eax , [ remap ]
  362. shr ebx , 5
  363. imul ecx , - 13
  364. mov [ counter_x ] , ebx
  365. lea ecx , [ ??remapref_point + ecx ]
  366. mov [ entry ] , ecx
  367. ??remapoutter_loop:
  368. mov ebx , [ counter_x ]
  369. push esi
  370. mov [ remap_counter ] , ebx
  371. push edi
  372. xor ecx , ecx
  373. xor ebx , ebx
  374. jmp [ entry ]
  375. ??remapinner_loop:
  376. REPT 32
  377. mov bl , [ esi ]
  378. add ecx , [ dx_frac ]
  379. adc esi , edx
  380. mov cl , [ eax + ebx ]
  381. mov [ edi ] , cl
  382. inc edi
  383. ENDM
  384. ??remapref_point:
  385. dec [ remap_counter ]
  386. jge ??remapinner_loop
  387. pop edi
  388. pop esi
  389. add edi , [ dst_win_width ]
  390. add esi , [ dy_intr ]
  391. mov ebx , [ dy_acc ]
  392. add ebx , [ dy_frac ]
  393. jle ??remapskip_line
  394. add esi , [ src_win_width ]
  395. sub ebx , [ dst_height ]
  396. ??remapskip_line:
  397. dec [ counter_y ]
  398. mov [ dy_acc ] , ebx
  399. jnz ??remapoutter_loop
  400. ret
  401. ;****************************************************************************
  402. ; scale with trnsparency
  403. ??transparency:
  404. cmp [ remap ] , 0
  405. jnz ??trans_remap
  406. ; *************************************************************************
  407. ; normal scale with transparency
  408. mov ecx , ebx
  409. and ecx , 01fh
  410. imul ecx , -13
  411. shr ebx , 5
  412. mov [ counter_x ] , ebx
  413. lea ecx , [ ??trans_ref_point + ecx ]
  414. mov [ entry ] , ecx
  415. ??trans_outter_loop:
  416. xor ecx , ecx
  417. push esi
  418. push edi
  419. mov ebx , [ counter_x ]
  420. jmp [ entry ]
  421. ??trans_inner_loop:
  422. REPT 32
  423. local trans_pixel
  424. mov cl , [ esi ]
  425. test cl , cl
  426. jz trans_pixel
  427. mov [ edi ] , cl
  428. trans_pixel:
  429. add ecx , eax
  430. adc esi , edx
  431. inc edi
  432. ENDM
  433. ??trans_ref_point:
  434. dec ebx
  435. jge ??trans_inner_loop
  436. pop edi
  437. pop esi
  438. add edi , [ dst_win_width ]
  439. add esi , [ dy_intr ]
  440. mov ebx , [ dy_acc ]
  441. add ebx , [ dy_frac ]
  442. jle ??trans_skip_line
  443. add esi , [ src_win_width ]
  444. sub ebx , [ dst_height ]
  445. ??trans_skip_line:
  446. dec [ counter_y ]
  447. mov [ dy_acc ] , ebx
  448. jnz ??trans_outter_loop
  449. ret
  450. ; *************************************************************************
  451. ; normal scale with remap
  452. ??trans_remap:
  453. mov ecx , ebx
  454. mov [ dx_frac ], eax
  455. and ecx , 01fh
  456. mov eax , [ remap ]
  457. shr ebx , 5
  458. imul ecx , - 17
  459. mov [ counter_x ] , ebx
  460. lea ecx , [ ??trans_remapref_point + ecx ]
  461. mov [ entry ] , ecx
  462. ??trans_remapoutter_loop:
  463. mov ebx , [ counter_x ]
  464. push esi
  465. mov [ remap_counter ] , ebx
  466. push edi
  467. xor ecx , ecx
  468. xor ebx , ebx
  469. jmp [ entry ]
  470. ??trans_remapinner_loop:
  471. REPT 32
  472. local trans_pixel
  473. mov bl , [ esi ]
  474. test bl , bl
  475. jz trans_pixel
  476. mov cl , [ eax + ebx ]
  477. mov [ edi ] , cl
  478. trans_pixel:
  479. add ecx , [ dx_frac ]
  480. adc esi , edx
  481. inc edi
  482. ENDM
  483. ??trans_remapref_point:
  484. dec [ remap_counter ]
  485. jge ??trans_remapinner_loop
  486. pop edi
  487. pop esi
  488. add edi , [ dst_win_width ]
  489. add esi , [ dy_intr ]
  490. mov ebx , [ dy_acc ]
  491. add ebx , [ dy_frac ]
  492. jle ??trans_remapskip_line
  493. add esi , [ src_win_width ]
  494. sub ebx , [ dst_height ]
  495. ??trans_remapskip_line:
  496. dec [ counter_y ]
  497. mov [ dy_acc ] , ebx
  498. jnz ??trans_remapoutter_loop
  499. ret
  500. ??all_done:
  501. ret
  502. endp
  503. END