vfx_map_polygon.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. #include "vfx.h"
  2. extern enum { CPU_UNKNOWN, CPU_PENTIUM, CPU_MMX, CPU_KATMAI } Processor;
  3. extern char AlphaTable[];
  4. static unsigned int SourceWidth,tWidth,tHeight,DestWidth; // Used for code optimizing
  5. static _int64 xmask=-1;
  6. //
  7. //
  8. // Draws a status bar
  9. //
  10. //
  11. void AG_StatusBar( PANE *pane, int X0, int Y0, int X1, int Y1, int Color, int Width )
  12. {
  13. static long TopY,BottomY;
  14. DestWidth = pane->window->x_max+1;
  15. long paneX0 = (pane->x0 < 0) ? 0 : pane->x0;
  16. long paneY0 = (pane->y0 < 0) ? 0 : pane->y0;
  17. long paneX1 = (pane->x1 >= (long)DestWidth) ? pane->window->x_max : pane->x1;
  18. long paneY1 = (pane->y1 >= (pane->window->y_max+1)) ? pane->window->y_max : pane->y1;
  19. if (X0>X1)
  20. {
  21. Width=-Width;
  22. TopY=X0;
  23. X0=X1;
  24. X1=TopY;
  25. }
  26. if (Y0>Y1)
  27. {
  28. TopY=Y0;
  29. Y0=Y1;
  30. Y1=TopY;
  31. }
  32. TopY=Y0;
  33. BottomY=Y1;
  34. if ( ( X0 >= paneX1 ) ||
  35. ( Y0 >= paneY1 ) ||
  36. ( X1 <= paneX0) ||
  37. ( Y1 <= paneY0))
  38. return;
  39. if( X0<paneX0 )
  40. {
  41. Width-=paneX0-X0;
  42. X0=paneX0;
  43. }
  44. if( Y0<paneY0 )
  45. Y0=paneY0;
  46. if( X1>paneX1 )
  47. X1=paneX1;
  48. if( Y1>paneY1 )
  49. Y1=paneY1;
  50. if( (X0+Width) >= X1 )
  51. Width=X1-X0-2;
  52. if( Width<0 )
  53. Width=0;
  54. if( X1-X0 < 3)
  55. return;
  56. UBYTE* DestPointer = pane->window->buffer + X0 + Y0*DestWidth;
  57. _asm{
  58. mov esi,Color
  59. mov edi,DestPointer
  60. sal esi,8
  61. mov ebx,X1
  62. add esi,offset AlphaTable
  63. sub ebx,X0
  64. mov ecx,Y0
  65. lp0:
  66. mov eax,TopY
  67. mov edx,BottomY
  68. cmp ecx,eax
  69. jz lp1
  70. cmp ecx,edx
  71. jz lp1
  72. //
  73. // Middle lines
  74. //
  75. //lp2:
  76. xor eax,eax
  77. xor edx,edx
  78. mov al,[edi]
  79. mov dl,[edi+ebx]
  80. mov al,[eax+(AlphaTable+S_BLACK*256)]
  81. mov dl,[edx+(AlphaTable+S_BLACK*256)]
  82. mov [edi],al
  83. mov [edi+ebx],dl
  84. mov edx,Width
  85. and edx,edx
  86. jz lp3
  87. inc edx
  88. push edi
  89. lp4:
  90. mov al,[edi+1]
  91. inc edi
  92. mov al,[esi+eax]
  93. dec edx
  94. mov [edi],al
  95. jnz lp4
  96. pop edi
  97. jmp lp3
  98. //
  99. // Top or bottom line
  100. //
  101. lp1:
  102. push edi
  103. mov edx,ebx
  104. xor eax,eax
  105. dec edx
  106. lp5:
  107. mov al,[edi+1]
  108. inc edi
  109. mov al,[eax+(AlphaTable+S_BLACK*256)]
  110. dec edx
  111. mov [edi],al
  112. jnz lp5
  113. pop edi
  114. nop
  115. lp3:
  116. mov eax,DestWidth
  117. mov edx,Y1
  118. add edi,eax
  119. inc ecx
  120. cmp edx,ecx
  121. jge lp0
  122. }
  123. }
  124. //
  125. //
  126. // Writes a single pixel
  127. //
  128. //
  129. void AG_pixel_write (PANE *pane, LONG x, LONG y, ULONG color)
  130. {
  131. int X=x+pane->x0;
  132. int Y=y+pane->y0;
  133. if( X>pane->x0 && X<pane->x1 && Y>pane->y0 && Y<pane->y1 )
  134. *(pane->window->buffer + X + Y*(pane->window->x_max+1))=(unsigned char)color;
  135. }
  136. //
  137. //
  138. // Draws a sprite - any colors marked 255 will be drawn transparent
  139. //
  140. //
  141. //
  142. long DrawTransparent( PANE *pane, WINDOW *texture, int X, int Y, int Width, int Height )
  143. {
  144. DestWidth = pane->window->x_max+1;
  145. long paneX0 = (pane->x0 < 0) ? 0 : pane->x0;
  146. long paneY0 = (pane->y0 < 0) ? 0 : pane->y0;
  147. long paneX1 = (pane->x1 >= (long)DestWidth) ? pane->window->x_max : pane->x1;
  148. long paneY1 = (pane->y1 >= (pane->window->y_max+1)) ? pane->window->y_max : pane->y1;
  149. X+=paneX0;
  150. Y+=paneY0;
  151. if ( ( X >= paneX1 ) ||
  152. ( Y >= paneY1 ) ||
  153. ( X <= (paneX0 - Width)) ||
  154. ( Y <= (paneY0 - Height)))
  155. return(1);
  156. UBYTE* SourcePointer = texture->buffer;
  157. if( X<paneX0 )
  158. {
  159. Width-=paneX0-X;
  160. SourcePointer+=paneX0-X;
  161. X=paneX0;
  162. }
  163. if( Y<paneY0 )
  164. {
  165. Height-=paneY0-Y;
  166. SourcePointer+=(paneY0-Y)*(texture->x_max+1);
  167. Y=paneY0;
  168. }
  169. if( X+Width > (paneX1+1) )
  170. Width= paneX1+1-X;
  171. if( Y+Height > (paneY1+1) )
  172. Height= paneY1+1-Y;
  173. UBYTE* DestPointer = pane->window->buffer + X + Y*DestWidth;
  174. SourceWidth=texture->x_max+1;
  175. tWidth=Width;
  176. tHeight=Height;
  177. _asm{
  178. cmp Processor,CPU_MMX
  179. jnz nonmmx
  180. push ebp
  181. mov edi,DestPointer
  182. mov esi,SourcePointer
  183. mov ebp,tWidth
  184. movq mm3,xmask
  185. Drawlpx:
  186. mov edx,ebp
  187. sub ebp,edi
  188. sub ebp,edx
  189. and ebp,7
  190. sub edx,ebp
  191. jle mt5a
  192. test ebp,ebp
  193. jz mt0b
  194. mt0: mov al,[esi]
  195. inc esi
  196. cmp al,255 ; Transfer enough bytes to align destination
  197. jz mt0a
  198. mov [edi],al
  199. mt0a: inc edi
  200. dec ebp
  201. jnz mt0
  202. mt0b: mov ebp,edx
  203. and edx,7
  204. shr ebp,3 ; ebp = number of quad words
  205. mov eax,esi
  206. mov ebx,8
  207. jz mt5a
  208. and eax,7
  209. and esi,-8
  210. movd mm5,eax
  211. nop
  212. sub ebx,eax
  213. add eax,esi
  214. xor ecx,ecx
  215. nop
  216. movq mm7,[esi+8]
  217. psllq mm5,3
  218. movd mm6,ebx
  219. movq mm4,mm7 ;Source 8 bytes
  220. movq mm0,[esi]
  221. psllq mm6,3
  222. movq mm2,mm3
  223. psrlq mm0,mm5
  224. ;
  225. ;
  226. ; MMX transparent blit inner loop - 1 cycle per byte. (Source+Dest 8 byte aligned, transparency not altered!)
  227. ;
  228. ;
  229. mt1: movq mm1,[edi+ecx] ;Desitination background
  230. psllq mm4,mm6
  231. por mm0,mm4
  232. lea ecx,[ecx+8]
  233. pcmpeqb mm2,mm0 ;mm2 = 0xff where transparent pixels in source
  234. dec ebp
  235. pand mm1,mm2 ;Only visible background left in mm1
  236. pandn mm2,mm0 ;Only visible image left in source
  237. movq mm4,[esi+ecx+8]
  238. por mm1,mm2 ;Combine visible background and source
  239. movq mm0,mm7 ;Source 8 bytes
  240. movq mm7,mm4
  241. movq [edi+ecx-8],mm1
  242. movq mm2,mm3
  243. psrlq mm0,mm5
  244. jnz mt1
  245. add edi,ecx
  246. lea esi,[eax+ecx]
  247. mt5a: add ebp,edx
  248. jz mt7
  249. mt6: mov al,[esi]
  250. inc esi
  251. cmp al,255 ; Finish off any last bytes
  252. jz mt8
  253. mov [edi],al
  254. mt8: inc edi
  255. dec ebp
  256. jnz mt6
  257. mt7: mov ebp,tWidth
  258. mov eax,tHeight
  259. sub edi,ebp
  260. sub esi,ebp
  261. mov ebx,DestWidth
  262. mov edx,SourceWidth
  263. add edi,ebx
  264. dec eax
  265. lea esi,[esi+edx]
  266. mov tHeight,eax
  267. jnz Drawlpx
  268. pop ebp
  269. emms
  270. jmp done
  271. //
  272. //
  273. // Non-mmx version of the transparent blit. - color 255 is transparent
  274. //
  275. //
  276. nonmmx:
  277. push ebp
  278. mov edi,DestPointer
  279. mov esi,SourcePointer
  280. mov ebp,tWidth
  281. Drawlp:
  282. mov edx,ebp
  283. sub ebp,edi
  284. sub ebp,edx
  285. and ebp,3
  286. sub edx,ebp
  287. jle dt5b
  288. test ebp,ebp
  289. jz dt0b
  290. dt0: mov al,[esi]
  291. inc esi
  292. cmp al,255 ; Transfer enough bytes to align destination
  293. jz dt0a
  294. mov [edi],al
  295. dt0a: inc edi
  296. dec ebp
  297. jnz dt0
  298. dt0b: mov ebp,edx
  299. and edx,3
  300. shr ebp,2
  301. jz dt5b
  302. dt1: mov ecx,[esi]
  303. lea esi,[esi+4]
  304. cmp ecx,-1 ; Quick check when all transparent
  305. jz dt5a
  306. mov eax,[edi]
  307. cmp cl,255
  308. jz dt2
  309. mov al,cl
  310. dt2: cmp ch,255
  311. jz dt3
  312. mov ah,ch
  313. dt3: rol eax,16 ; Transfer data in DWORD chunks
  314. shr ecx,16
  315. cmp cl,255
  316. jz dt4
  317. mov al,cl
  318. dt4: cmp ch,255
  319. jz dt5
  320. mov ah,ch
  321. dt5: ror eax,16
  322. mov [edi],eax
  323. dt5a: lea edi,[edi+4]
  324. dec ebp
  325. jnz dt1
  326. dt5b: add ebp,edx
  327. jz dt7
  328. dt6: mov al,[esi]
  329. inc esi
  330. cmp al,255 ; Finish off any last bytes
  331. jz dt8
  332. mov [edi],al
  333. dt8: inc edi
  334. dec ebp
  335. jnz dt6
  336. dt7: mov ebp,tWidth
  337. mov eax,tHeight
  338. sub edi,ebp
  339. sub esi,ebp
  340. mov ebx,DestWidth
  341. mov edx,SourceWidth
  342. add edi,ebx
  343. dec eax
  344. lea esi,[esi+edx]
  345. mov tHeight,eax
  346. jnz Drawlp
  347. pop ebp
  348. done:
  349. }
  350. return 0;
  351. }