SCALE.ASM 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  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 "mcgaprim.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: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 ] ; get ptr to src
  126. xor ecx , ecx
  127. xor edx , edx
  128. mov edi , [ (VideoViewPort esi) . VIVPWidth ] ; 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,[ ( VideoViewPort esi) . VIVPHeight ] ; 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 , [ (VideoViewPort esi) . VIVPWidth ] ; 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 , [ (VideoViewPort esi) . VIVPHeight ] ; 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 , [ (VideoViewPort esi) . VIVPWidth ] ; 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,[ ( VideoViewPort esi) . VIVPHeight ] ; 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 , [ (VideoViewPort esi) . VIVPWidth ] ; 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 , [ (VideoViewPort esi) . VIVPHeight ] ; 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 ]
  270. mov esi , [ (VideoViewPort ebx) . VIVPOffset ]
  271. mov eax , [ (VideoViewPort ebx) . VIVPXAdd ]
  272. add eax , [ (VideoViewPort ebx) . VIVPWidth ]
  273. mov [ src_win_width ] , eax
  274. mul [ src_y0 ]
  275. add esi , [ src_x0 ]
  276. add esi , eax
  277. mov ebx , [ dest ]
  278. mov edi , [ (VideoViewPort ebx) . VIVPOffset ]
  279. mov eax , [ (VideoViewPort ebx) . VIVPXAdd ]
  280. add eax , [ (VideoViewPort ebx) . VIVPWidth ]
  281. mov [ dst_win_width ] , eax
  282. mul [ dst_y0 ]
  283. add edi , [ dst_x0 ]
  284. add edi , eax
  285. mov eax , [ src_height ]
  286. xor edx , edx
  287. mov ebx , [ dst_height ]
  288. idiv [ dst_height ]
  289. imul eax , [ src_win_width ]
  290. neg ebx
  291. mov [ dy_intr ] , eax
  292. mov [ dy_frac ] , edx
  293. mov [ dy_acc ] , ebx
  294. mov eax , [ src_width ]
  295. xor edx , edx
  296. shl eax , 16
  297. idiv [ dst_width ]
  298. xor edx , edx
  299. shld edx , eax , 16
  300. shl eax , 16
  301. mov ecx , [ dst_y1 ]
  302. mov ebx , [ dst_x1 ]
  303. sub ecx , [ dst_y0 ]
  304. jle ??all_done
  305. sub ebx , [ dst_x0 ]
  306. jle ??all_done
  307. mov [ counter_y ] , ecx
  308. cmp [ trans ] , 0
  309. jnz ??transparency
  310. cmp [ remap ] , 0
  311. jnz ??normal_remap
  312. ; *************************************************************************
  313. ; normal scale
  314. mov ecx , ebx
  315. and ecx , 01fh
  316. lea ecx , [ ecx + ecx * 2 ]
  317. shr ebx , 5
  318. neg ecx
  319. mov [ counter_x ] , ebx
  320. lea ecx , [ ??ref_point + ecx + ecx * 2 ]
  321. mov [ entry ] , ecx
  322. ??outter_loop:
  323. push esi
  324. push edi
  325. xor ecx , ecx
  326. mov ebx , [ counter_x ]
  327. jmp [ entry ]
  328. ??inner_loop:
  329. REPT 32
  330. mov cl , [ esi ]
  331. add ecx , eax
  332. adc esi , edx
  333. mov [ edi ] , cl
  334. inc edi
  335. ENDM
  336. ??ref_point:
  337. dec ebx
  338. jge ??inner_loop
  339. pop edi
  340. pop esi
  341. add edi , [ dst_win_width ]
  342. add esi , [ dy_intr ]
  343. mov ebx , [ dy_acc ]
  344. add ebx , [ dy_frac ]
  345. jle ??skip_line
  346. add esi , [ src_win_width ]
  347. sub ebx , [ dst_height ]
  348. ??skip_line:
  349. dec [ counter_y ]
  350. mov [ dy_acc ] , ebx
  351. jnz ??outter_loop
  352. ret
  353. ; *************************************************************************
  354. ; normal scale with remap
  355. ??normal_remap:
  356. mov ecx , ebx
  357. mov [ dx_frac ], eax
  358. and ecx , 01fh
  359. mov eax , [ remap ]
  360. shr ebx , 5
  361. imul ecx , - 13
  362. mov [ counter_x ] , ebx
  363. lea ecx , [ ??remapref_point + ecx ]
  364. mov [ entry ] , ecx
  365. ??remapoutter_loop:
  366. mov ebx , [ counter_x ]
  367. push esi
  368. mov [ remap_counter ] , ebx
  369. push edi
  370. xor ecx , ecx
  371. xor ebx , ebx
  372. jmp [ entry ]
  373. ??remapinner_loop:
  374. REPT 32
  375. mov bl , [ esi ]
  376. add ecx , [ dx_frac ]
  377. adc esi , edx
  378. mov cl , [ eax + ebx ]
  379. mov [ edi ] , cl
  380. inc edi
  381. ENDM
  382. ??remapref_point:
  383. dec [ remap_counter ]
  384. jge ??remapinner_loop
  385. pop edi
  386. pop esi
  387. add edi , [ dst_win_width ]
  388. add esi , [ dy_intr ]
  389. mov ebx , [ dy_acc ]
  390. add ebx , [ dy_frac ]
  391. jle ??remapskip_line
  392. add esi , [ src_win_width ]
  393. sub ebx , [ dst_height ]
  394. ??remapskip_line:
  395. dec [ counter_y ]
  396. mov [ dy_acc ] , ebx
  397. jnz ??remapoutter_loop
  398. ret
  399. ;****************************************************************************
  400. ; scale with trnsparency
  401. ??transparency:
  402. cmp [ remap ] , 0
  403. jnz ??trans_remap
  404. ; *************************************************************************
  405. ; normal scale with transparency
  406. mov ecx , ebx
  407. and ecx , 01fh
  408. imul ecx , -13
  409. shr ebx , 5
  410. mov [ counter_x ] , ebx
  411. lea ecx , [ ??trans_ref_point + ecx ]
  412. mov [ entry ] , ecx
  413. ??trans_outter_loop:
  414. xor ecx , ecx
  415. push esi
  416. push edi
  417. mov ebx , [ counter_x ]
  418. jmp [ entry ]
  419. ??trans_inner_loop:
  420. REPT 32
  421. local trans_pixel
  422. mov cl , [ esi ]
  423. test cl , cl
  424. jz trans_pixel
  425. mov [ edi ] , cl
  426. trans_pixel:
  427. add ecx , eax
  428. adc esi , edx
  429. inc edi
  430. ENDM
  431. ??trans_ref_point:
  432. dec ebx
  433. jge ??trans_inner_loop
  434. pop edi
  435. pop esi
  436. add edi , [ dst_win_width ]
  437. add esi , [ dy_intr ]
  438. mov ebx , [ dy_acc ]
  439. add ebx , [ dy_frac ]
  440. jle ??trans_skip_line
  441. add esi , [ src_win_width ]
  442. sub ebx , [ dst_height ]
  443. ??trans_skip_line:
  444. dec [ counter_y ]
  445. mov [ dy_acc ] , ebx
  446. jnz ??trans_outter_loop
  447. ret
  448. ; *************************************************************************
  449. ; normal scale with remap
  450. ??trans_remap:
  451. mov ecx , ebx
  452. mov [ dx_frac ], eax
  453. and ecx , 01fh
  454. mov eax , [ remap ]
  455. shr ebx , 5
  456. imul ecx , - 17
  457. mov [ counter_x ] , ebx
  458. lea ecx , [ ??trans_remapref_point + ecx ]
  459. mov [ entry ] , ecx
  460. ??trans_remapoutter_loop:
  461. mov ebx , [ counter_x ]
  462. push esi
  463. mov [ remap_counter ] , ebx
  464. push edi
  465. xor ecx , ecx
  466. xor ebx , ebx
  467. jmp [ entry ]
  468. ??trans_remapinner_loop:
  469. REPT 32
  470. local trans_pixel
  471. mov bl , [ esi ]
  472. test bl , bl
  473. jz trans_pixel
  474. mov cl , [ eax + ebx ]
  475. mov [ edi ] , cl
  476. trans_pixel:
  477. add ecx , [ dx_frac ]
  478. adc esi , edx
  479. inc edi
  480. ENDM
  481. ??trans_remapref_point:
  482. dec [ remap_counter ]
  483. jge ??trans_remapinner_loop
  484. pop edi
  485. pop esi
  486. add edi , [ dst_win_width ]
  487. add esi , [ dy_intr ]
  488. mov ebx , [ dy_acc ]
  489. add ebx , [ dy_frac ]
  490. jle ??trans_remapskip_line
  491. add esi , [ src_win_width ]
  492. sub ebx , [ dst_height ]
  493. ??trans_remapskip_line:
  494. dec [ counter_y ]
  495. mov [ dy_acc ] , ebx
  496. jnz ??trans_remapoutter_loop
  497. ret
  498. ??all_done:
  499. ret
  500. endp
  501. END