VVBLIT.ASM 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  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 : BITBLIT.ASM *
  25. ;* *
  26. ;* Programmer : Phil W. Gorrow *
  27. ;* *
  28. ;* Start Date : June 8, 1994 *
  29. ;* *
  30. ;* Last Update : December 13, 1994 [PWG] *
  31. ;* *
  32. ;*-------------------------------------------------------------------------*
  33. ;* Functions: *
  34. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  35. IDEAL
  36. P386
  37. MODEL USE32 FLAT
  38. LOCALS ??
  39. INCLUDE "svgaprim.inc"
  40. INCLUDE "gbuffer.inc"
  41. TRANSP equ 0
  42. POOLSIZE equ 8000
  43. CODESEG
  44. PROC Vesa_Blit_To_Vesa C near
  45. USES ebx,ecx,edx,esi,edi
  46. ;*===================================================================
  47. ;* define the arguements that our function takes.
  48. ;*===================================================================
  49. ARG this :DWORD ; this is a member function
  50. ARG dest :DWORD ; what are we blitting to
  51. ARG x_pixel :DWORD ; x pixel position in source
  52. ARG y_pixel :DWORD ; y pixel position in source
  53. ARG dest_x0 :dword
  54. ARG dest_y0 :dword
  55. ARG pixel_width :DWORD ; width of rectangle to blit
  56. ARG pixel_height:DWORD ; height of rectangle to blit
  57. ARG trans :DWORD ; do we deal with transparents?
  58. ;*===================================================================
  59. ; Define some locals so that we can handle things quickly
  60. ;*===================================================================
  61. LOCAL x1_pixel :dword
  62. LOCAL y1_pixel :dword
  63. LOCAL dest_x1 : dword
  64. LOCAL dest_y1 : dword
  65. LOCAL scr_ajust_width:DWORD
  66. LOCAL dest_ajust_width:DWORD
  67. LOCAL source_area : dword
  68. LOCAL dest_area : dword
  69. local total_lines : dword
  70. local count_dy : dword
  71. local mem_page : dword
  72. local vesa_page : dword
  73. local mem_pool : byte : POOLSIZE
  74. ; Clip Source Rectangle against source Window boundaries.
  75. mov esi , [ this ] ; get ptr to src
  76. xor ecx , ecx
  77. xor edx , edx
  78. mov edi , [ (VideoViewPort esi) . VIVPWidth ] ; get width into register
  79. mov ebx , [ x_pixel ]
  80. mov eax , [ x_pixel ]
  81. add ebx , [ pixel_width ]
  82. shld ecx , eax , 1
  83. mov [ x1_pixel ] , ebx
  84. inc edi
  85. shld edx , ebx , 1
  86. sub eax , edi
  87. sub ebx , edi
  88. shld ecx , eax , 1
  89. shld edx , ebx , 1
  90. mov edi,[ ( VideoViewPort esi) . VIVPHeight ] ; get height into register
  91. mov ebx , [ y_pixel ]
  92. mov eax , [ y_pixel ]
  93. add ebx , [ pixel_height ]
  94. shld ecx , eax , 1
  95. mov [ y1_pixel ] , ebx
  96. inc edi
  97. shld edx , ebx , 1
  98. sub eax , edi
  99. sub ebx , edi
  100. shld ecx , eax , 1
  101. shld edx , ebx , 1
  102. xor cl , 5
  103. xor dl , 5
  104. mov al , cl
  105. test dl , cl
  106. jnz ??real_out
  107. or al , dl
  108. jz ??clip_against_dest
  109. test cl , 1000b
  110. jz ??scr_left_ok
  111. mov [ x_pixel ] , 0
  112. ??scr_left_ok:
  113. test cl , 0010b
  114. jz ??scr_bottom_ok
  115. mov [ y_pixel ] , 0
  116. ??scr_bottom_ok:
  117. test dl , 0100b
  118. jz ??scr_right_ok
  119. mov eax , [ (VideoViewPort esi) . VIVPWidth ] ; get width into register
  120. mov [ x1_pixel ] , eax
  121. ??scr_right_ok:
  122. test dl , 0001b
  123. jz ??clip_against_dest
  124. mov eax , [ (VideoViewPort esi) . VIVPHeight ] ; get width into register
  125. mov [ y1_pixel ] , eax
  126. ; Clip Source Rectangle against destination Window boundaries.
  127. ??clip_against_dest:
  128. mov eax , [ dest_x0 ]
  129. mov ebx , [ dest_y0 ]
  130. sub eax , [ x_pixel ]
  131. sub ebx , [ y_pixel ]
  132. add eax , [ x1_pixel ]
  133. add ebx , [ y1_pixel ]
  134. mov [ dest_x1 ] , eax
  135. mov [ dest_y1 ] , ebx
  136. mov esi , [ dest ] ; get ptr to src
  137. xor ecx , ecx
  138. xor edx , edx
  139. mov edi , [ (VideoViewPort esi) . VIVPWidth ] ; get width into register
  140. mov eax , [ dest_x0 ]
  141. mov ebx , [ dest_x1 ]
  142. shld ecx , eax , 1
  143. inc edi
  144. shld edx , ebx , 1
  145. sub eax , edi
  146. sub ebx , edi
  147. shld ecx , eax , 1
  148. shld edx , ebx , 1
  149. mov edi,[ ( VideoViewPort esi) . VIVPHeight ] ; get height into register
  150. mov eax , [ dest_y0 ]
  151. mov ebx , [ dest_y1 ]
  152. shld ecx , eax , 1
  153. inc edi
  154. shld edx , ebx , 1
  155. sub eax , edi
  156. sub ebx , edi
  157. shld ecx , eax , 1
  158. shld edx , ebx , 1
  159. xor cl , 5
  160. xor dl , 5
  161. mov al , cl
  162. test dl , cl
  163. jnz ??real_out
  164. or al , dl
  165. jz ??do_blit
  166. test cl , 1000b
  167. jz ??dest_left_ok
  168. mov eax , [ dest_x0 ]
  169. mov [ dest_x0 ] , 0
  170. sub [ x_pixel ] , eax
  171. ??dest_left_ok:
  172. test cl , 0010b
  173. jz ??dest_bottom_ok
  174. mov eax , [ dest_y0 ]
  175. mov [ dest_y0 ] , 0
  176. sub [ y_pixel ] , eax
  177. ??dest_bottom_ok:
  178. test dl , 0100b
  179. jz ??dest_right_ok
  180. mov ebx , [ (VideoViewPort esi) . VIVPWidth ] ; get width into register
  181. mov eax , [ dest_x1 ]
  182. mov [ dest_x1 ] , ebx
  183. sub eax , ebx
  184. sub [ x1_pixel ] , eax
  185. ??dest_right_ok:
  186. test dl , 0001b
  187. jz ??do_blit
  188. mov ebx , [ (VideoViewPort esi) . VIVPHeight ] ; get width into register
  189. mov eax , [ dest_y1 ]
  190. mov [ dest_y1 ] , ebx
  191. sub eax , ebx
  192. sub [ y1_pixel ] , eax
  193. ??do_blit:
  194. cld
  195. mov ebx , [ this ]
  196. mov esi , [ (VideoViewPort ebx) . VIVPOffset ]
  197. mov eax , [ (VideoViewPort ebx) . VIVPXAdd ]
  198. add eax , [ (VideoViewPort ebx) . VIVPWidth ]
  199. mov ecx , eax
  200. mul [ y_pixel ]
  201. add esi , [ x_pixel ]
  202. mov [ source_area ] , ecx
  203. add esi , eax
  204. add ecx , [ x_pixel ]
  205. sub ecx , [ x1_pixel ]
  206. mov [ scr_ajust_width ] , ecx
  207. mov ebx , [ dest ]
  208. mov edi , [ (VideoViewPort ebx) . VIVPOffset ]
  209. mov eax , [ (VideoViewPort ebx) . VIVPXAdd ]
  210. add eax , [ (VideoViewPort ebx) . VIVPWidth ]
  211. mov ecx , eax
  212. mul [ dest_y0 ]
  213. add edi , [ dest_x0 ]
  214. mov [ dest_area ] , ecx
  215. add edi , eax
  216. mov eax , [ dest_x1 ]
  217. sub eax , [ dest_x0 ]
  218. jz ??real_out
  219. sub ecx , eax
  220. mov [ dest_ajust_width ] , ecx
  221. mov edx , [ dest_y1 ]
  222. sub edx , [ dest_y0 ]
  223. jz ??real_out
  224. push eax
  225. mov [ mem_page ] , 0
  226. mov [ vesa_page ] , 0
  227. mov [ total_lines ] , edx
  228. mov eax , POOLSIZE
  229. xor edx , edx
  230. idiv [ dword ptr esp ]
  231. mov [ count_dy ] , eax
  232. pop eax
  233. ; **************************************************************************
  234. ; check direction of motions
  235. cmp esi , edi
  236. jl ??backupward_blit
  237. ret
  238. ;***********************************************************************
  239. ; Backupward blit
  240. ??back_mem_loop:
  241. push edi
  242. lea edi , [ mem_pool ]
  243. mov edx , [ count_dy ]
  244. call ??vesa_to_memory
  245. pop edi
  246. push esi
  247. lea esi , [ mem_pool ]
  248. mov edx , [ count_dy ]
  249. call ??memory_to_vesa
  250. pop esi
  251. ??backupward_blit:
  252. mov edx , [ total_lines ]
  253. sub edx , [ count_dy ]
  254. mov [ total_lines ] , edx
  255. jg ??back_mem_loop
  256. add edx , [ count_dy ]
  257. push edi
  258. push edx
  259. lea edi , [ mem_pool ]
  260. call ??vesa_to_memory
  261. pop edx
  262. pop edi
  263. push esi
  264. lea esi , [ mem_pool ]
  265. call ??memory_to_vesa
  266. pop esi
  267. ret
  268. ??real_out:
  269. ret
  270. ; ********************************************************************
  271. ; Move Vesa video page to memory buffer
  272. ??vesa_to_memory:
  273. xchg edi , esi
  274. add edi , [ mem_page ]
  275. call Vesa_Asm_Set_Win
  276. xchg edi , esi
  277. IF TRANSP
  278. test [ trans ] , 1
  279. jnz ??tomem_forward_Blit_trans
  280. ENDIF
  281. ; the inner loop is so efficient that
  282. ; the optimal consept no longer apply because
  283. ; the optimal byte have to by a number greather than 9 bytes
  284. cmp eax , 10
  285. jl ??tomem_forward_loop_bytes
  286. ??tomem_forward_loop_dword:
  287. lea ebx , [ esi + eax ]
  288. add ebx , [ cpu_video_page ]
  289. cmp ebx , [ cpu_page_limit ]
  290. jl ??tomem_in_range
  291. xor ecx , ecx
  292. mov ebx , eax
  293. cmp esi , 0b0000h
  294. jge ??tomem_no_trailing
  295. mov ecx , 0b0000h
  296. sub ecx , esi
  297. sub ebx , ecx
  298. rep movsb
  299. ??tomem_no_trailing:
  300. add esi , [ cpu_video_page ]
  301. xchg edi , esi
  302. Call Vesa_Asm_Set_Win ; set the window
  303. xchg edi , esi
  304. mov ecx , ebx
  305. rep movsb
  306. add esi , [ scr_ajust_width ]
  307. dec edx ; decrement the height
  308. jnz ??tomem_forward_loop_dword
  309. mov edx , [ cpu_video_page ]
  310. mov [ mem_page ] , edx
  311. retn
  312. ??tomem_in_range:
  313. mov ecx , edi
  314. mov ebx , eax
  315. neg ecx
  316. and ecx , 3
  317. sub ebx , ecx
  318. rep movsb
  319. mov ecx , ebx
  320. shr ecx , 2
  321. rep movsd
  322. mov ecx , ebx
  323. and ecx , 3
  324. rep movsb
  325. add esi , [ scr_ajust_width ]
  326. dec edx
  327. jnz ??tomem_forward_loop_dword
  328. mov edx , [ cpu_video_page ]
  329. mov [ mem_page ] , edx
  330. retn
  331. ??tomem_forward_loop_bytes:
  332. lea ebx , [ esi + eax ]
  333. add ebx , [ cpu_video_page ]
  334. cmp ebx , [ cpu_page_limit ]
  335. mov ebx , eax
  336. jl ??tomem_in_range_bytes
  337. xor ecx , ecx
  338. cmp esi , 0b0000h
  339. jge ??tomem_no_trailing_bytes
  340. mov ecx , 0b0000h
  341. sub ecx , esi
  342. sub ebx , ecx
  343. rep movsb
  344. ??tomem_no_trailing_bytes:
  345. add esi , [ cpu_video_page ]
  346. xchg edi , esi
  347. Call Vesa_Asm_Set_Win ; set the window
  348. xchg edi , esi
  349. ??tomem_in_range_bytes:
  350. mov ecx , ebx
  351. rep movsb
  352. add esi , [ scr_ajust_width ]
  353. dec edx ; decrement the height
  354. jnz ??tomem_forward_loop_bytes
  355. mov edx , [ cpu_video_page ]
  356. mov [ mem_page ] , edx
  357. retn
  358. IF TRANSP
  359. ??tomem_forward_Blit_trans:
  360. mov ecx , eax
  361. and ecx , 01fh
  362. lea ecx , [ ecx + ecx * 4 ]
  363. neg ecx
  364. shr eax , 5
  365. lea ecx , [ ??tomem_transp_reference + ecx * 2 ]
  366. mov [ y1_pixel ] , ecx
  367. ??tomem_forward_loop_trans:
  368. mov ecx , eax
  369. jmp [ y1_pixel ]
  370. ??tomem_forward_trans_line:
  371. REPT 32
  372. local transp_pixel
  373. mov bl , [ esi ]
  374. inc esi
  375. test bl , bl
  376. jz transp_pixel
  377. mov [ edi ] , bl
  378. transp_pixel:
  379. inc edi
  380. ENDM
  381. ??tomem_transp_reference:
  382. dec ecx
  383. jge ??tomem_forward_trans_line
  384. add esi , [ scr_ajust_width ]
  385. dec edx
  386. jnz ??tomem_forward_loop_trans
  387. mov edx , [ cpu_video_page ]
  388. mov [ mem_page ] , edx
  389. retn
  390. ENDIF
  391. ;*************************************************************************
  392. ; copy from memory to vesa page
  393. ??memory_to_vesa:
  394. add edi , [ vesa_page ]
  395. Call Vesa_Asm_Set_Win
  396. IF TRANSP
  397. test [ trans ] , 1
  398. jnz ??tovesa_forward_Blit_trans
  399. ENDIF
  400. ; the inner loop is so efficient that
  401. ; the optimal consept no longer apply because
  402. ; the optimal byte have to by a number greather than 9 bytes
  403. cmp eax , 10
  404. jl ??tovesa_forward_loop_bytes
  405. ??tovesa_forward_loop_dword:
  406. lea ebx , [ edi + eax ]
  407. add ebx , [ cpu_video_page ]
  408. cmp ebx , [ cpu_page_limit ]
  409. jl ??tovesa_in_range
  410. xor ecx , ecx
  411. cmp edi , 0b0000h
  412. mov ebx , eax
  413. jge ??tovesa_no_trailing
  414. mov ecx , 0b0000h
  415. sub ecx , edi
  416. sub ebx , ecx
  417. rep movsb
  418. ??tovesa_no_trailing:
  419. add edi , [ cpu_video_page ]
  420. Call Vesa_Asm_Set_Win ; set the window
  421. mov ecx , ebx
  422. rep movsb
  423. add edi , [ dest_ajust_width ]
  424. dec edx ; decrement the height
  425. jnz ??tovesa_forward_loop_dword
  426. mov edx , [ cpu_video_page ]
  427. mov [ vesa_page ] , edx
  428. retn
  429. ??tovesa_in_range:
  430. mov ecx , edi
  431. mov ebx , eax
  432. neg ecx
  433. and ecx , 3
  434. sub ebx , ecx
  435. rep movsb
  436. mov ecx , ebx
  437. shr ecx , 2
  438. rep movsd
  439. mov ecx , ebx
  440. and ecx , 3
  441. rep movsb
  442. add edi , [ dest_ajust_width ]
  443. dec edx
  444. jnz ??tovesa_forward_loop_dword
  445. mov edx , [ cpu_video_page ]
  446. mov [ vesa_page ] , edx
  447. retn
  448. ??tovesa_forward_loop_bytes:
  449. lea ebx , [ edi + eax ]
  450. add ebx , [ cpu_video_page ]
  451. cmp ebx , [ cpu_page_limit ]
  452. mov ebx , eax
  453. jl ??tovesa_in_range_bytes
  454. xor ecx , ecx
  455. cmp edi , 0b0000h
  456. jge ??tovesa_no_trailing_bytes
  457. mov ecx , 0b0000h
  458. sub ecx , edi
  459. sub ebx , ecx
  460. rep movsb
  461. ??tovesa_no_trailing_bytes:
  462. add edi , [ cpu_video_page ]
  463. Call Vesa_Asm_Set_Win ; set the window
  464. ??tovesa_in_range_bytes:
  465. mov ecx , ebx
  466. rep movsb
  467. add edi , [ dest_ajust_width ]
  468. dec edx ; decrement the height
  469. jnz ??tovesa_forward_loop_bytes
  470. mov edx , [ cpu_video_page ]
  471. mov [ vesa_page ] , edx
  472. retn
  473. IF TRANSP
  474. ??tovesa_forward_Blit_trans:
  475. mov ecx , eax
  476. and ecx , 01fh
  477. lea ecx , [ ecx + ecx * 4 ]
  478. neg ecx
  479. shr eax , 5
  480. lea ecx , [ ??tovesa_transp_reference + ecx * 2 ]
  481. mov [ y1_pixel ] , ecx
  482. ??tovesa_forward_loop_trans:
  483. mov ecx , eax
  484. jmp [ y1_pixel ]
  485. ??tovesa_forward_trans_line:
  486. REPT 32
  487. local transp_pixel
  488. mov bl , [ esi ]
  489. test bl , bl
  490. jz transp_pixel
  491. mov [ edi ] , bl
  492. transp_pixel:
  493. inc esi
  494. inc edi
  495. ENDM
  496. ??tovesa_transp_reference:
  497. dec ecx
  498. jge ??tovesa_forward_trans_line
  499. add edi , [ dest_ajust_width ]
  500. dec edx
  501. jnz ??tovesa_forward_loop_trans
  502. mov edx , [ cpu_video_page ]
  503. mov [ vesa_page ] , edx
  504. retn
  505. ENDIF
  506. ENDP Vesa_Blit_To_Vesa
  507. END