STAMP.ASM 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  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 S T U D I O S **
  20. ;***************************************************************************
  21. ;* *
  22. ;* Project Name : Westwood Library *
  23. ;* *
  24. ;* File Name : STAMP.ASM *
  25. ;* *
  26. ;* Programmer : Joe L. Bostic *
  27. ;* *
  28. ;* Start Date : August 23, 1993 *
  29. ;* *
  30. ;* Last Update : August 23, 1993 [JLB] *
  31. ;* *
  32. ;*-------------------------------------------------------------------------*
  33. ;* Functions: *
  34. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  35. IDEAL
  36. P386
  37. MODEL USE32 FLAT
  38. INCLUDE ".\drawbuff.inc"
  39. INCLUDE ".\gbuffer.inc"
  40. INCLUDE "stamp.inc"
  41. global C Init_Stamps:near
  42. global LastIconset:dword
  43. global MapPtr:dword
  44. global IconCount:dword
  45. global IconSize:dword
  46. global StampPtr:dword
  47. DATASEG
  48. LastIconset DD 0 ; Pointer to last iconset initialized.
  49. StampPtr DD 0 ; Pointer to icon data.
  50. IsTrans DD 0 ; Pointer to transparent icon flag table.
  51. MapPtr DD 0 ; Pointer to icon map.
  52. IconWidth DD 0 ; Width of icon in pixels.
  53. IconHeight DD 0 ; Height of icon in pixels.
  54. IconSize DD 0 ; Number of bytes for each icon data.
  55. IconCount DD 0 ; Number of icons in the set.
  56. EVEN
  57. CODESEG
  58. GLOBAL C Buffer_Draw_Stamp:near
  59. GLOBAL C Buffer_Draw_Stamp_Clip:near
  60. ; 256 color icon system.
  61. ;***********************************************************
  62. ; INIT_STAMPS
  63. ;
  64. ; VOID cdecl Init_Stamps(VOID *icondata);
  65. ;
  66. ; This routine initializes the stamp data.
  67. ; Bounds Checking: NONE
  68. ;
  69. ;*
  70. PROC Init_Stamps C near USES eax ebx edx edi
  71. ARG icondata:DWORD
  72. ; Verify legality of parameter.
  73. cmp [icondata],0
  74. je short ??fini
  75. ; Don't initialize if already initialized to this set (speed reasons).
  76. mov edi,[icondata]
  77. cmp [LastIconset],edi
  78. je short ??fini
  79. mov [LastIconset],edi
  80. ; Record number of icons in set.
  81. movzx eax,[(IControl_Type edi).Count]
  82. mov [IconCount],eax
  83. ; Record width of icon.
  84. movzx eax,[(IControl_Type edi).Width]
  85. mov [IconWidth],eax
  86. ; Record height of icon.
  87. movzx ebx,[(IControl_Type edi).Height]
  88. mov [IconHeight],ebx
  89. ; Record size of icon (in bytes).
  90. mul ebx
  91. mov [IconSize],eax
  92. ; Record hard pointer to icon map data.
  93. mov eax,[(IControl_Type edi).Map]
  94. add eax,edi
  95. mov [MapPtr],eax
  96. ??nomap:
  97. ; Record hard pointer to icon data.
  98. mov eax,edi
  99. add eax,[(IControl_Type edi).Icons]
  100. mov [StampPtr],eax
  101. ; Record the transparent table.
  102. mov eax,edi
  103. add eax,[(IControl_Type edi).TransFlag]
  104. mov [IsTrans],eax
  105. ??fini:
  106. ret
  107. ENDP Init_Stamps
  108. ;***********************************************************
  109. ;***********************************************************
  110. ; DRAW_STAMP
  111. ;
  112. ; VOID cdecl Buffer_Draw_Stamp(VOID *icondata, WORD icon, WORD x_pixel, WORD y_pixel, VOID *remap);
  113. ;
  114. ; This routine renders the icon at the given coordinate.
  115. ;
  116. ; The remap table is a 256 byte simple pixel translation table to use when
  117. ; drawing the icon. Transparency check is performed AFTER the remap so it is possible to
  118. ; remap valid colors to be invisible (for special effect reasons).
  119. ; This routine is fastest when no remap table is passed in.
  120. ;*
  121. PROC Buffer_Draw_Stamp C near
  122. ARG this_object:DWORD ; this is a member function
  123. ARG icondata:DWORD ; Pointer to icondata.
  124. ARG icon:DWORD ; Icon number to draw.
  125. ARG x_pixel:DWORD ; X coordinate of icon.
  126. ARG y_pixel:DWORD ; Y coordinate of icon.
  127. ARG remap:DWORD ; Remap table.
  128. LOCAL modulo:DWORD ; Modulo to get to next row.
  129. LOCAL iwidth:DWORD ; Icon width (here for speedy access).
  130. LOCAL doremap:BYTE ; Should remapping occur?
  131. pushad
  132. cmp [icondata],0
  133. je ??out
  134. ; Initialize the stamp data if necessary.
  135. mov eax,[icondata]
  136. cmp [LastIconset],eax
  137. je short ??noreset
  138. call Init_Stamps C,eax
  139. ??noreset:
  140. ; Determine if the icon number requested is actually in the set.
  141. ; Perform the logical icon to actual icon number remap if necessary.
  142. mov ebx,[icon]
  143. cmp [MapPtr],0
  144. je short ??notmap
  145. mov edi,[MapPtr]
  146. mov bl,[edi+ebx]
  147. ??notmap:
  148. cmp ebx,[IconCount]
  149. jae ??out
  150. mov [icon],ebx ; Updated icon number.
  151. ; If the remap table pointer passed in is NULL, then flag this condition
  152. ; so that the faster (non-remapping) icon draw loop will be used.
  153. cmp [remap],0
  154. setne [doremap]
  155. ; Get pointer to position to render icon. EDI = ptr to destination page.
  156. mov ebx,[this_object]
  157. mov edi,[(GraphicViewPort ebx).GVPOffset]
  158. mov eax,[(GraphicViewPort ebx).GVPWidth]
  159. add eax,[(GraphicViewPort ebx).GVPXAdd]
  160. add eax,[(GraphicViewPort ebx).GVPPitch]
  161. push eax ; save viewport full width for lower
  162. mul [y_pixel]
  163. add edi,eax
  164. add edi,[x_pixel]
  165. ; Determine row modulo for advancing to next line.
  166. pop eax ; retrieve viewport width
  167. sub eax,[IconWidth]
  168. mov [modulo],eax
  169. ; Setup some working variables.
  170. mov ecx,[IconHeight] ; Row counter.
  171. mov eax,[IconWidth]
  172. mov [iwidth],eax ; Stack copy of byte width for easy BP access.
  173. ; Fetch pointer to start of icon's data. ESI = ptr to icon data.
  174. mov eax,[icon]
  175. mul [IconSize]
  176. mov esi,[StampPtr]
  177. add esi,eax
  178. ; Determine whether simple icon draw is sufficient or whether the
  179. ; extra remapping icon draw is needed.
  180. cmp [BYTE PTR doremap],0
  181. je short ??istranscheck
  182. ;************************************************************
  183. ; Complex icon draw -- extended remap.
  184. ; EBX = Palette pointer (ready for XLAT instruction).
  185. ; EDI = Pointer to icon destination in page.
  186. ; ESI = Pointer to icon data.
  187. ; ECX = Number of pixel rows.
  188. ;;; mov edx,[remap]
  189. mov ebx,[remap]
  190. xor eax,eax
  191. ??xrowloop:
  192. push ecx
  193. mov ecx,[iwidth]
  194. ??xcolumnloop:
  195. lodsb
  196. ;;; mov ebx,edx
  197. ;;; add ebx,eax
  198. ;;; mov al,[ebx] ; New real color to draw.
  199. xlatb
  200. or al,al
  201. jz short ??xskip1 ; Transparency skip check.
  202. mov [edi],al
  203. ??xskip1:
  204. inc edi
  205. loop ??xcolumnloop
  206. pop ecx
  207. add edi,[modulo]
  208. loop ??xrowloop
  209. jmp short ??out
  210. ;************************************************************
  211. ; Check to see if transparent or generic draw is necessary.
  212. ??istranscheck:
  213. mov ebx,[IsTrans]
  214. add ebx,[icon]
  215. cmp [BYTE PTR ebx],0
  216. jne short ??rowloop
  217. ;************************************************************
  218. ; Fast non-transparent icon draw routine.
  219. ; ES:DI = Pointer to icon destination in page.
  220. ; DS:SI = Pointer to icon data.
  221. ; CX = Number of pixel rows.
  222. mov ebx,ecx
  223. shr ebx,2
  224. mov edx,[modulo]
  225. mov eax,[iwidth]
  226. shr eax,2
  227. ??loop1:
  228. mov ecx,eax
  229. rep movsd
  230. add edi,edx
  231. mov ecx,eax
  232. rep movsd
  233. add edi,edx
  234. mov ecx,eax
  235. rep movsd
  236. add edi,edx
  237. mov ecx,eax
  238. rep movsd
  239. add edi,edx
  240. dec ebx
  241. jnz ??loop1
  242. jmp short ??out
  243. ;************************************************************
  244. ; Transparent icon draw routine -- no extended remap.
  245. ; ES:DI = Pointer to icon destination in page.
  246. ; DS:SI = Pointer to icon data.
  247. ; CX = Number of pixel rows.
  248. ??rowloop:
  249. push ecx
  250. mov ecx,[iwidth]
  251. ??columnloop:
  252. lodsb
  253. or al,al
  254. jz short ??skip1 ; Transparency check.
  255. mov [edi],al
  256. ??skip1:
  257. inc edi
  258. loop ??columnloop
  259. pop ecx
  260. add edi,[modulo]
  261. loop ??rowloop
  262. ; Cleanup and exit icon drawing routine.
  263. ??out:
  264. popad
  265. ret
  266. ENDP Buffer_Draw_Stamp
  267. ;***********************************************************
  268. ; DRAW_STAMP_CLIP
  269. ;
  270. ; VOID cdecl MCGA_Draw_Stamp_Clip(VOID *icondata, WORD icon, WORD x_pixel, WORD y_pixel, VOID *remap, LONG min_x, LONG min_y, LONG max_x, LONG max_y);
  271. ;
  272. ; This routine renders the icon at the given coordinate.
  273. ;
  274. ; The remap table is a 256 byte simple pixel translation table to use when
  275. ; drawing the icon. Transparency check is performed AFTER the remap so it is possible to
  276. ; remap valid colors to be invisible (for special effect reasons).
  277. ; This routine is fastest when no remap table is passed in.
  278. ;*
  279. PROC Buffer_Draw_Stamp_Clip C near
  280. ARG this_object:DWORD ; this is a member function
  281. ARG icondata:DWORD ; Pointer to icondata.
  282. ARG icon:DWORD ; Icon number to draw.
  283. ARG x_pixel:DWORD ; X coordinate of icon.
  284. ARG y_pixel:DWORD ; Y coordinate of icon.
  285. ARG remap:DWORD ; Remap table.
  286. ARG min_x:DWORD ; Clipping rectangle boundary
  287. ARG min_y:DWORD ; Clipping rectangle boundary
  288. ARG max_x:DWORD ; Clipping rectangle boundary
  289. ARG max_y:DWORD ; Clipping rectangle boundary
  290. LOCAL modulo:DWORD ; Modulo to get to next row.
  291. LOCAL iwidth:DWORD ; Icon width (here for speedy access).
  292. LOCAL skip:DWORD ; amount to skip per row of icon data
  293. LOCAL doremap:BYTE ; Should remapping occur?
  294. pushad
  295. cmp [icondata],0
  296. je ??out2
  297. ; Initialize the stamp data if necessary.
  298. mov eax,[icondata]
  299. cmp [LastIconset],eax
  300. je short ??noreset2
  301. call Init_Stamps C,eax
  302. ??noreset2:
  303. ; Determine if the icon number requested is actually in the set.
  304. ; Perform the logical icon to actual icon number remap if necessary.
  305. mov ebx,[icon]
  306. cmp [MapPtr],0
  307. je short ??notmap2
  308. mov edi,[MapPtr]
  309. mov bl,[edi+ebx]
  310. ??notmap2:
  311. cmp ebx,[IconCount]
  312. jae ??out2
  313. mov [icon],ebx ; Updated icon number.
  314. ; Setup some working variables.
  315. mov ecx,[IconHeight] ; Row counter.
  316. mov eax,[IconWidth]
  317. mov [iwidth],eax ; Stack copy of byte width for easy BP access.
  318. ; Fetch pointer to start of icon's data. ESI = ptr to icon data.
  319. mov eax,[icon]
  320. mul [IconSize]
  321. mov esi,[StampPtr]
  322. add esi,eax
  323. ; Update the clipping window coordinates to be valid maxes instead of width & height
  324. ; , and change the coordinates to be window-relative
  325. mov ebx,[min_x]
  326. add [max_x],ebx
  327. add [x_pixel],ebx ; make it window-relative
  328. mov ebx,[min_y]
  329. add [max_y],ebx
  330. add [y_pixel],ebx ; make it window-relative
  331. ; See if the icon is within the clipping window
  332. ; First, verify that the icon position is less than the maximums
  333. mov ebx,[x_pixel]
  334. cmp ebx,[max_x]
  335. jge ??out2
  336. mov ebx,[y_pixel]
  337. cmp ebx,[max_y]
  338. jge ??out2
  339. ; Now verify that the icon position is >= the minimums
  340. add ebx,[IconHeight]
  341. cmp ebx,[min_y]
  342. jle ??out2
  343. mov ebx,[x_pixel]
  344. add ebx,[IconWidth]
  345. cmp ebx,[min_x]
  346. jle ??out2
  347. ; Now, clip the x, y, width, and height variables to be within the
  348. ; clipping rectangle
  349. mov ebx,[x_pixel]
  350. cmp ebx,[min_x]
  351. jge ??nominxclip
  352. ; x < minx, so must clip
  353. mov ebx,[min_x]
  354. sub ebx,[x_pixel]
  355. add esi,ebx ; source ptr += (minx - x)
  356. sub [iwidth],ebx ; icon width -= (minx - x)
  357. mov ebx,[min_x]
  358. mov [x_pixel],ebx
  359. ??nominxclip:
  360. mov eax,[IconWidth]
  361. sub eax,[iwidth]
  362. mov [skip],eax
  363. ; Check for x+width > max_x
  364. mov eax,[x_pixel]
  365. add eax,[iwidth]
  366. cmp eax,[max_x]
  367. jle ??nomaxxclip
  368. ; x+width is greater than max_x, so must clip width down
  369. mov eax,[iwidth] ; eax = old width
  370. mov ebx,[max_x]
  371. sub ebx,[x_pixel]
  372. mov [iwidth],ebx ; iwidth = max_x - xpixel
  373. sub eax,ebx
  374. add [skip],eax ; skip += (old width - iwidth)
  375. ??nomaxxclip:
  376. ; check if y < miny
  377. mov eax,[min_y]
  378. cmp eax,[y_pixel] ; if(miny <= y_pixel), no clip needed
  379. jle ??nominyclip
  380. sub eax,[y_pixel]
  381. sub ecx,eax ; height -= (miny - y)
  382. mul [IconWidth]
  383. add esi,eax ; icon source ptr += (width * (miny - y))
  384. mov eax,[min_y]
  385. mov [y_pixel],eax ; y = miny
  386. ??nominyclip:
  387. ; check if (y+height) > max y
  388. mov eax,[y_pixel]
  389. add eax,ecx
  390. cmp eax,[max_y] ; if (y + height <= max_y), no clip needed
  391. jle ??nomaxyclip
  392. mov ecx,[max_y] ; height = max_y - y_pixel
  393. sub ecx,[y_pixel]
  394. ??nomaxyclip:
  395. ; If the remap table pointer passed in is NULL, then flag this condition
  396. ; so that the faster (non-remapping) icon draw loop will be used.
  397. cmp [remap],0
  398. setne [doremap]
  399. ; Get pointer to position to render icon. EDI = ptr to destination page.
  400. mov ebx,[this_object]
  401. mov edi,[(GraphicViewPort ebx).GVPOffset]
  402. mov eax,[(GraphicViewPort ebx).GVPWidth]
  403. add eax,[(GraphicViewPort ebx).GVPXAdd]
  404. add eax,[(GraphicViewPort ebx).GVPPitch]
  405. push eax ; save viewport full width for lower
  406. mul [y_pixel]
  407. add edi,eax
  408. add edi,[x_pixel]
  409. ; Determine row modulo for advancing to next line.
  410. pop eax ; retrieve viewport width
  411. sub eax,[iwidth]
  412. mov [modulo],eax
  413. ; Determine whether simple icon draw is sufficient or whether the
  414. ; extra remapping icon draw is needed.
  415. cmp [BYTE PTR doremap],0
  416. je short ??istranscheck2
  417. ;************************************************************
  418. ; Complex icon draw -- extended remap.
  419. ; EBX = Palette pointer (ready for XLAT instruction).
  420. ; EDI = Pointer to icon destination in page.
  421. ; ESI = Pointer to icon data.
  422. ; ECX = Number of pixel rows.
  423. mov ebx,[remap]
  424. xor eax,eax
  425. ??xrowloopc:
  426. push ecx
  427. mov ecx,[iwidth]
  428. ??xcolumnloopc:
  429. lodsb
  430. xlatb
  431. or al,al
  432. jz short ??xskip1c ; Transparency skip check.
  433. mov [edi],al
  434. ??xskip1c:
  435. inc edi
  436. loop ??xcolumnloopc
  437. pop ecx
  438. add edi,[modulo]
  439. add esi,[skip]
  440. loop ??xrowloopc
  441. jmp short ??out2
  442. ;************************************************************
  443. ; Check to see if transparent or generic draw is necessary.
  444. ??istranscheck2:
  445. mov ebx,[IsTrans]
  446. add ebx,[icon]
  447. cmp [BYTE PTR ebx],0
  448. jne short ??rowloopc
  449. ;************************************************************
  450. ; Fast non-transparent icon draw routine.
  451. ; ES:DI = Pointer to icon destination in page.
  452. ; DS:SI = Pointer to icon data.
  453. ; CX = Number of pixel rows.
  454. mov ebx,ecx
  455. mov edx,[modulo]
  456. mov eax,[iwidth]
  457. ;
  458. ; Optimise copy by dword aligning the destination
  459. ;
  460. ??loop1c:
  461. push eax
  462. rept 3
  463. test edi,3
  464. jz ??aligned
  465. movsb
  466. dec eax
  467. jz ??finishedit
  468. endm
  469. ??aligned:
  470. mov ecx,eax
  471. shr ecx,2
  472. rep movsd
  473. mov ecx,eax
  474. and ecx,3
  475. rep movsb
  476. ??finishedit:
  477. add edi,edx
  478. add esi,[skip]
  479. pop eax
  480. dec ebx
  481. jnz ??loop1c
  482. jmp short ??out2
  483. ;************************************************************
  484. ; Transparent icon draw routine -- no extended remap.
  485. ; ES:DI = Pointer to icon destination in page.
  486. ; DS:SI = Pointer to icon data.
  487. ; CX = Number of pixel rows.
  488. ??rowloopc:
  489. push ecx
  490. mov ecx,[iwidth]
  491. ??columnloopc:
  492. lodsb
  493. or al,al
  494. jz short ??skip1c ; Transparency check.
  495. mov [edi],al
  496. ??skip1c:
  497. inc edi
  498. loop ??columnloopc
  499. pop ecx
  500. add edi,[modulo]
  501. add esi,[skip]
  502. loop ??rowloopc
  503. ; Cleanup and exit icon drawing routine.
  504. ??out2:
  505. popad
  506. ret
  507. ENDP Buffer_Draw_Stamp_Clip
  508. END