vfx_translatedraw.cpp 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733
  1. #include "dstd.h"
  2. #include "vfx.h"
  3. #include <stdio.h>
  4. extern char AlphaTable[256*256];
  5. typedef struct
  6. {
  7. DWORD bounds;
  8. DWORD origin;
  9. DWORD xmin;
  10. DWORD ymin;
  11. DWORD xmax;
  12. DWORD ymax;
  13. } SHAPEHEADER;
  14. //
  15. // Sprite format
  16. //
  17. //
  18. // Marker.
  19. // 0 End of line
  20. // 1 Skip next bytes
  21. // Bit 0 = 0 Repeat next byte [7654321] times
  22. // Bit 0 = 1 String packet [7654321] bytes
  23. //
  24. unsigned int lookaside;
  25. static unsigned int tempXmax,tempXmin;
  26. static unsigned int minX,minY,maxY,SkipLeft,NewWidth,StartofLine,StartofClip,EndofClip;
  27. static unsigned int lines,DestWidth,paneX0,paneX1,paneY0,paneY1;
  28. /*
  29. ;
  30. ; int cdecl VFX_shape_draw (PANE *panep, void *shape_table,
  31. ; long shape_number,int hotX, int hotY)
  32. ;
  33. ; This function clips and draws a shape to a pane.
  34. ;
  35. ; The panep parameter specifies the pane.
  36. ;
  37. ; The shape parameter specifies the shape, which must be in VFX Shape format.
  38. ;
  39. ; The hotX and hotY parameters specify the location where the shape is to be
  40. ; drawn. The shape's hot spot will end up at the specified location.
  41. ;
  42. */
  43. void AG_shape_draw (PANE *pane, void *shape_table,LONG shape_number, LONG hotX, LONG hotY)
  44. {
  45. _asm{
  46. mov esi,shape_table
  47. mov eax,shape_number
  48. mov ecx,[esi+eax*8+8]
  49. cmp word ptr [esi+ecx+SIZE SHAPEHEADER],3 ; (String packet, 0)
  50. jz AlphaDraw
  51. mov edi,pane
  52. nop
  53. ;
  54. ; Clip left and right of clipping window
  55. ;
  56. mov ecx,[edi+PANE.x0]
  57. mov edx,[edi+PANE.y0]
  58. mov ebx,ecx
  59. mov eax,edx
  60. sar ebx,31
  61. xor eax,-1
  62. sar eax,31 ; If less than 0, make 0
  63. xor ebx,-1
  64. and ecx,ebx
  65. and edx,eax
  66. mov paneX0,ecx
  67. mov paneY0,edx
  68. ;
  69. ; Clip top and bottom of clipping window
  70. ;
  71. mov ecx,[edi+PANE.x1]
  72. mov edx,[edi+PANE.y1]
  73. mov edi,[edi+PANE.window]
  74. mov esi,shape_table
  75. mov eax,[edi+WINDOW.x_max]
  76. xor ebx,ebx
  77. inc eax
  78. nop
  79. sub ecx,eax
  80. mov DestWidth,eax
  81. setge bl
  82. dec ebx ; if ecx is less than eax, load ecx with eax
  83. nop
  84. and ecx,ebx
  85. mov ebx,[edi+WINDOW.y_max]
  86. add ecx,eax
  87. inc ebx
  88. xor eax,eax
  89. sub edx,ebx
  90. setge al
  91. dec eax
  92. mov paneX1,ecx
  93. and edx,eax
  94. mov eax,shape_number
  95. add edx,ebx
  96. mov ebx,paneY0
  97. ;
  98. ; paneX0,Y0 to PaneX1,Y1 are 0,0 -> 639,479 or window size to render too
  99. ;
  100. mov ecx,[esi+eax*8+8] ; ESI now points to start of sprite data
  101. mov paneY1,edx
  102. lea esi,[esi+ecx+SIZE SHAPEHEADER]
  103. mov edx,hotY
  104. mov ecx,[esi+SHAPEHEADER.xmax-SIZE SHAPEHEADER]
  105. mov eax,[esi+SHAPEHEADER.xmin-SIZE SHAPEHEADER]
  106. mov tempXmax,ecx ; Store Xmax and Xmin
  107. mov tempXmin,eax
  108. mov ecx,[esi+SHAPEHEADER.ymax-SIZE SHAPEHEADER]
  109. mov eax,[esi+SHAPEHEADER.ymin-SIZE SHAPEHEADER]
  110. sub ecx,eax ; ecx = Height of sprite
  111. add eax,edx ; eax = top line
  112. inc ecx ; Add one line
  113. nop
  114. ;
  115. ; Now check for lines off the top of the clipping window
  116. ;
  117. cmp eax,ebx
  118. jl ClippedTop
  119. ;
  120. ; Now check for lines off the bottom of the clipping window
  121. ;
  122. rw5:
  123. lea ebx,[eax+ecx-1] ; ebx=Last Line
  124. nop
  125. sub ebx,paneY1 ; Check to see if off bottom
  126. ja ClippedBottom
  127. rw6:
  128. mov lines,ecx ; eax still equals top line
  129. ;
  130. ; Now check clipping in X
  131. ;
  132. mov ebx,tempXmax
  133. mov ecx,tempXmin
  134. mov edx,paneX0
  135. sub ebx,ecx ; ebx = Width of sprite
  136. add ecx,hotX ; ecx = offset to left edge
  137. cmp ecx,edx ; Is sprite off left edge of screen?
  138. jl ClippedLeft
  139. lea edx,[ebx+ecx]
  140. mov edi,[edi+WINDOW.buffer] ; edi points to top left of buffer
  141. sub edx,paneX1
  142. jnbe ClippedRight
  143. ;
  144. ; Work out screen position
  145. ;
  146. //NowDraw:
  147. imul DestWidth
  148. add eax,ecx
  149. xor ecx,ecx
  150. add edi,eax
  151. mov StartofLine,edi
  152. ;
  153. ;
  154. ; Main drawing loop
  155. ;
  156. ;
  157. lineLoop:
  158. mov al,[esi]
  159. inc esi
  160. shr al,1
  161. ja RunPacket
  162. jnz StringPacket
  163. jnc EndPacket
  164. //SkipPacket:
  165. xor ecx,ecx
  166. mov cl,[esi]
  167. inc esi
  168. add edi,ecx
  169. jmp lineLoop
  170. RunPacket:
  171. mov cl,[esi]
  172. inc esi
  173. rp1:
  174. mov [edi],cl
  175. inc edi
  176. dec al
  177. jnz rp1
  178. jmp lineLoop
  179. StringPacket:
  180. //
  181. // 17 cycles / 8 bytes - 2.125 per byte
  182. //
  183. sub al,8
  184. jc sp2
  185. sp1:
  186. mov ecx,[esi]
  187. mov ebx,[esi+4]
  188. mov [edi],ecx
  189. mov [edi+4],ebx
  190. add esi,8
  191. add edi,8
  192. sub al,8
  193. jnc sp1
  194. sp2:
  195. add al,8
  196. jz lineLoop
  197. sp3:
  198. mov cl,[esi]
  199. inc esi
  200. mov [edi],cl
  201. inc edi
  202. dec al
  203. jnz sp3
  204. jmp lineLoop
  205. EndPacket:
  206. mov edx,DestWidth
  207. mov edi,StartofLine
  208. add edi,edx
  209. mov edx,lines
  210. dec edx
  211. mov StartofLine,edi
  212. mov lines,edx
  213. jnz lineLoop
  214. jmp Exit
  215. ;
  216. ;
  217. ; Lines are clipped off the bottom of the clip window
  218. ;
  219. ;
  220. ClippedBottom:
  221. sub ecx,ebx ; Remove lines that go off bottom
  222. jbe Exit
  223. jmp rw6
  224. ;
  225. ;
  226. ; Lines are off the top of the clip window
  227. ;
  228. ;
  229. ClippedTop:
  230. sub ebx,eax ; ebx=Lines to skip
  231. xor eax,eax
  232. sub ecx,ebx ; ecx=Lines in sprite
  233. jbe Exit ; Off top of screen
  234. rw8:
  235. mov al,[esi]
  236. add esi,2
  237. shr al,1
  238. ja rw8
  239. jnz rw8StringPacket ; Skip over lines in sprite data
  240. jc rw8
  241. dec esi
  242. dec ebx
  243. jnz rw8
  244. mov eax,paneY0 ; eax=top line
  245. jmp rw5
  246. rw8StringPacket:
  247. lea esi,[esi+eax-1]
  248. jmp rw8
  249. ;
  250. ;
  251. ; Sprite is clipped on either left or right
  252. ;
  253. ;
  254. ClippedLeft:
  255. sub edx,ecx
  256. mov edi,[edi+WINDOW.buffer] ; edi points to top left of buffer
  257. cmp ebx,edx
  258. jbe Exit ; Completly off left of screen?
  259. jmp ClippedX
  260. ClippedRight:
  261. cmp ecx,edx ; Completly off right of screen?
  262. jbe Exit
  263. ClippedX:
  264. imul DestWidth
  265. add edi,eax
  266. mov eax,paneX0
  267. mov edx,paneX1
  268. add eax,edi
  269. add edx,edi ; eax=Last pixel on right edge of clip window
  270. mov ebx,eax
  271. add edi,ecx
  272. xor ecx,ecx
  273. mov StartofLine,edi
  274. ;
  275. ; Clipped left and/or right drawing loop
  276. ;
  277. clineLoop:
  278. mov al,[esi]
  279. inc esi
  280. shr al,1
  281. ja cRunPacket
  282. jnz cStringPacket
  283. jnc cEndPacket
  284. //cSkipPacket:
  285. xor ecx,ecx
  286. mov cl,[esi]
  287. inc esi
  288. add edi,ecx
  289. jmp clineLoop
  290. cRunPacket:
  291. mov cl,[esi]
  292. inc esi
  293. crp1:
  294. cmp edi,ebx
  295. jc crp2
  296. cmp edi,edx
  297. jnbe clineLoop
  298. mov [edi],cl
  299. crp2:
  300. inc edi
  301. dec al
  302. jnz crp1
  303. jmp clineLoop
  304. cStringPacket:
  305. mov cl,[esi]
  306. inc esi
  307. cmp edi,ebx
  308. jc crp3
  309. cmp edi,edx
  310. jnbe crp3a
  311. mov [edi],cl
  312. crp3:
  313. inc edi
  314. dec al
  315. jnz cStringPacket
  316. jmp clineLoop
  317. crp3a:
  318. and eax,255
  319. lea esi,[esi+eax-1]
  320. jmp clineLoop
  321. cEndPacket:
  322. mov eax,DestWidth
  323. mov edi,StartofLine
  324. add edx,eax
  325. add edi,eax
  326. add ebx,eax
  327. mov eax,lines
  328. mov StartofLine,edi
  329. dec eax
  330. mov lines,eax
  331. jnz clineLoop
  332. jmp Exit
  333. //
  334. //
  335. // Same routine as above, but using Alpha table
  336. //
  337. //
  338. AlphaDraw:
  339. mov edi,pane
  340. nop
  341. ;
  342. ; Clip left and right of clipping window
  343. ;
  344. mov ecx,[edi+PANE.x0]
  345. mov edx,[edi+PANE.y0]
  346. mov ebx,ecx
  347. mov eax,edx
  348. sar ebx,31
  349. xor eax,-1
  350. sar eax,31 ; If less than 0, make 0
  351. xor ebx,-1
  352. and ecx,ebx
  353. and edx,eax
  354. mov paneX0,ecx
  355. mov paneY0,edx
  356. ;
  357. ; Clip top and bottom of clipping window
  358. ;
  359. mov ecx,[edi+PANE.x1]
  360. mov edx,[edi+PANE.y1]
  361. mov edi,[edi+PANE.window]
  362. mov esi,shape_table
  363. mov eax,[edi+WINDOW.x_max]
  364. xor ebx,ebx
  365. inc eax
  366. nop
  367. sub ecx,eax
  368. mov DestWidth,eax
  369. setge bl
  370. dec ebx ; if ecx is less than eax, load ecx with eax
  371. nop
  372. and ecx,ebx
  373. mov ebx,[edi+WINDOW.y_max]
  374. add ecx,eax
  375. inc ebx
  376. xor eax,eax
  377. sub edx,ebx
  378. setge al
  379. dec eax
  380. mov paneX1,ecx
  381. and edx,eax
  382. mov eax,shape_number
  383. add edx,ebx
  384. mov ebx,paneY0
  385. ;
  386. ; paneX0,Y0 to PaneX1,Y1 are 0,0 -> 639,479 or window size to render too
  387. ;
  388. mov ecx,[esi+eax*8+8] ; ESI now points to start of sprite data
  389. mov paneY1,edx
  390. lea esi,[esi+ecx+SIZE SHAPEHEADER]
  391. mov edx,hotY
  392. mov ecx,[esi+SHAPEHEADER.xmax-SIZE SHAPEHEADER]
  393. mov eax,[esi+SHAPEHEADER.xmin-SIZE SHAPEHEADER]
  394. mov tempXmax,ecx ; Store Xmax and Xmin
  395. mov tempXmin,eax
  396. mov ecx,[esi+SHAPEHEADER.ymax-SIZE SHAPEHEADER]
  397. mov eax,[esi+SHAPEHEADER.ymin-SIZE SHAPEHEADER]
  398. sub ecx,eax ; ecx = Height of sprite
  399. add eax,edx ; eax = top line
  400. inc ecx ; Add one line
  401. nop
  402. ;
  403. ; Now check for lines off the top of the clipping window
  404. ;
  405. cmp eax,ebx
  406. jl aClippedTop
  407. ;
  408. ; Now check for lines off the bottom of the clipping window
  409. ;
  410. arw5:
  411. lea ebx,[eax+ecx] ; ebx=Last Line
  412. nop
  413. sub ebx,paneY1 ; Check to see if off bottom
  414. ja aClippedBottom
  415. arw6:
  416. mov lines,ecx ; eax still equals top line
  417. ;
  418. ; Now check clipping in X
  419. ;
  420. mov ebx,tempXmax
  421. mov ecx,tempXmin
  422. mov edx,paneX0
  423. sub ebx,ecx ; ebx = Width of sprite
  424. add ecx,hotX ; ecx = offset to left edge
  425. inc ecx
  426. nop
  427. cmp ecx,edx ; Is sprite off left edge of screen?
  428. jl aClippedLeft
  429. lea edx,[ebx+ecx]
  430. mov edi,[edi+WINDOW.buffer] ; edi points to top left of buffer
  431. sub edx,paneX1
  432. ja aClippedRight
  433. ;
  434. ; Work out screen position
  435. ;
  436. //aNowDraw:
  437. imul DestWidth
  438. add eax,ecx
  439. xor ecx,ecx
  440. add edi,eax
  441. mov StartofLine,edi
  442. ;
  443. ;
  444. ; Main drawing loop
  445. ;
  446. ;
  447. alineLoop:
  448. mov al,[esi]
  449. inc esi
  450. shr al,1
  451. ja aRunPacket
  452. jnz aStringPacket
  453. jnc aEndPacket
  454. //aSkipPacket:
  455. xor ecx,ecx
  456. mov cl,[esi]
  457. inc esi
  458. add edi,ecx
  459. jmp alineLoop
  460. aRunPacket:
  461. mov ch,[esi]
  462. inc esi
  463. arp1:
  464. mov cl,[edi]
  465. inc edi
  466. mov cl,AlphaTable[ecx]
  467. dec al
  468. mov [edi-1],cl
  469. jnz arp1
  470. jmp alineLoop
  471. aStringPacket:
  472. mov ch,[esi]
  473. inc esi
  474. mov cl,[edi]
  475. inc edi
  476. mov cl,AlphaTable[ecx]
  477. dec al
  478. mov [edi-1],cl
  479. jnz aStringPacket
  480. jmp alineLoop
  481. aEndPacket:
  482. mov edx,DestWidth
  483. mov edi,StartofLine
  484. add edi,edx
  485. mov edx,lines
  486. dec edx
  487. mov StartofLine,edi
  488. mov lines,edx
  489. jnz alineLoop
  490. jmp Exit
  491. ;
  492. ;
  493. ; Lines are clipped off the bottom of the clip window
  494. ;
  495. ;
  496. aClippedBottom:
  497. sub ecx,ebx ; Remove lines that go off bottom
  498. jbe Exit
  499. jmp arw6
  500. ;
  501. ;
  502. ; Lines are off the top of the clip window
  503. ;
  504. ;
  505. aClippedTop:
  506. sub ebx,eax ; ebx=Lines to skip
  507. xor eax,eax
  508. sub ecx,ebx ; ecx=Lines in sprite
  509. jbe Exit ; Off top of screen
  510. arw8:
  511. mov al,[esi]
  512. add esi,2
  513. shr al,1
  514. ja arw8
  515. jnz arw8StringPacket ; Skip over lines in sprite data
  516. jc arw8
  517. dec esi
  518. dec ebx
  519. jnz arw8
  520. mov eax,paneY0 ; eax=top line
  521. jmp arw5
  522. arw8StringPacket:
  523. lea esi,[esi+eax-1]
  524. jmp arw8
  525. ;
  526. ;
  527. ; Sprite is clipped on either left or right
  528. ;
  529. ;
  530. aClippedLeft:
  531. sub edx,ecx
  532. mov edi,[edi+WINDOW.buffer] ; edi points to top left of buffer
  533. cmp ebx,edx
  534. jbe Exit ; Completly off left of screen?
  535. jmp aClippedX
  536. aClippedRight:
  537. cmp ecx,edx ; Completly off right of screen?
  538. jbe Exit
  539. aClippedX:
  540. imul DestWidth
  541. add edi,eax
  542. mov eax,paneX0
  543. mov edx,paneX1
  544. add eax,edi
  545. add edx,edi ; eax=Last pixel on right edge of clip window
  546. mov ebx,eax
  547. add edi,ecx
  548. mov StartofLine,edi
  549. xor ecx,ecx
  550. ;
  551. ; Clipped left and/or right drawing loop
  552. ;
  553. aclineLoop:
  554. mov al,[esi]
  555. inc esi
  556. shr al,1
  557. ja acRunPacket
  558. jnz acStringPacket
  559. jnc acEndPacket
  560. //acSkipPacket:
  561. xor ecx,ecx
  562. mov cl,[esi]
  563. inc esi
  564. add edi,ecx
  565. jmp aclineLoop
  566. acRunPacket:
  567. mov ch,[esi]
  568. inc esi
  569. acrp1:
  570. cmp edi,ebx
  571. jc acrp2
  572. cmp edi,edx
  573. jnbe aclineLoop
  574. mov cl,[edi]
  575. mov cl,AlphaTable[ecx]
  576. mov [edi],cl
  577. acrp2:
  578. inc edi
  579. dec al
  580. jnz acrp1
  581. jmp aclineLoop
  582. acStringPacket:
  583. mov ch,[esi]
  584. inc esi
  585. cmp edi,ebx
  586. jc acrp3
  587. cmp edi,edx
  588. jnbe acrp3a
  589. mov cl,[edi]
  590. mov cl,AlphaTable[ecx]
  591. mov [edi],cl
  592. acrp3:
  593. inc edi
  594. dec al
  595. jnz acStringPacket
  596. jmp aclineLoop
  597. acrp3a:
  598. and eax,255
  599. lea esi,[esi+eax-1]
  600. jmp aclineLoop
  601. acEndPacket:
  602. mov eax,DestWidth
  603. mov edi,StartofLine
  604. add edx,eax
  605. add edi,eax
  606. add ebx,eax
  607. mov eax,lines
  608. mov StartofLine,edi
  609. dec eax
  610. mov lines,eax
  611. jnz aclineLoop
  612. Exit:
  613. }
  614. }
  615. /*
  616. ;----------------------------------------------------------------------------
  617. ;
  618. ; void cdecl VFX_shape_lookaside (unsigned char *table)
  619. ;
  620. ; Establishes a color translation lookaside table for use by future calls
  621. ; to VFX_shape_translate_draw().
  622. ;
  623. ; table points to a 256-byte table specifying remap values for each of
  624. ; the 256 possible palette indices. The table is copied to static local
  625. ; memory, and need not remain valid after the call.
  626. ;
  627. ;----------------------------------------------------------------------------
  628. */
  629. void AG_shape_lookaside( UBYTE *table )
  630. {
  631. _asm{
  632. mov eax,table
  633. mov lookaside,eax
  634. }
  635. }
  636. /*
  637. ;----------------------------------------------------------------------------
  638. ;
  639. ; int cdecl VFX_shape_translate_draw (PANE *panep, void *shape_table,
  640. ; long shape_number,int hotX, int hotY)
  641. ;
  642. ; This function clips and draws a shape to a pane. It is identical to
  643. ; VFX_shape_draw(), except that each pixel written is translated through a
  644. ; 256-byte table which was specified by a prior call to VFX_shape_lookaside().
  645. ;
  646. ; The panep parameter specifies the pane.
  647. ;
  648. ; The shape parameter specifies the shape, which must be in VFX Shape format.
  649. ;
  650. ; The hotX and hotY parameters specify the location where the shape is to be
  651. ; drawn. The shape's hot spot will end up at the specified location.
  652. ;
  653. ; For more information, see the "VFX Shape Format Description".
  654. ;
  655. ; Return values:
  656. ;
  657. ; 0: OK
  658. ; -1: Bad window
  659. ; -2: Bad pane
  660. ; -3: Shape off pane
  661. ; -4: Null shape
  662. ;
  663. ;----------------------------------------------------------------------------
  664. */
  665. void AG_shape_translate_draw (PANE *pane, void *shape_table,LONG shape_number, LONG hotX, LONG hotY)
  666. {
  667. _asm{
  668. mov esi,shape_table
  669. mov eax,shape_number
  670. mov ecx,[esi+eax*8+8]
  671. cmp word ptr [esi+ecx+SIZE SHAPEHEADER],3 ; (String packet, 0)
  672. jz AlphaDraw
  673. mov edi,pane
  674. nop
  675. ;
  676. ; Clip left and right of clipping window
  677. ;
  678. mov ecx,[edi+PANE.x0]
  679. mov edx,[edi+PANE.y0]
  680. mov ebx,ecx
  681. mov eax,edx
  682. sar ebx,31
  683. xor eax,-1
  684. sar eax,31 ; If less than 0, make 0
  685. xor ebx,-1
  686. and ecx,ebx
  687. and edx,eax
  688. mov paneX0,ecx
  689. mov paneY0,edx
  690. ;
  691. ; Clip top and bottom of clipping window
  692. ;
  693. mov ecx,[edi+PANE.x1]
  694. mov edx,[edi+PANE.y1]
  695. mov edi,[edi+PANE.window]
  696. mov esi,shape_table
  697. mov eax,[edi+WINDOW.x_max]
  698. xor ebx,ebx
  699. inc eax
  700. nop
  701. sub ecx,eax
  702. mov DestWidth,eax
  703. setge bl
  704. dec ebx ; if ecx is less than eax, load ecx with eax
  705. nop
  706. and ecx,ebx
  707. mov ebx,[edi+WINDOW.y_max]
  708. add ecx,eax
  709. inc ebx
  710. xor eax,eax
  711. sub edx,ebx
  712. setge al
  713. dec eax
  714. mov paneX1,ecx
  715. and edx,eax
  716. mov eax,shape_number
  717. add edx,ebx
  718. mov ebx,paneY0
  719. ;
  720. ; paneX0,Y0 to PaneX1,Y1 are 0,0 -> 639,479 or window size to render too
  721. ;
  722. mov ecx,[esi+eax*8+8] ; ESI now points to start of sprite data
  723. mov paneY1,edx
  724. lea esi,[esi+ecx+SIZE SHAPEHEADER]
  725. mov edx,hotY
  726. mov ecx,[esi+SHAPEHEADER.xmax-SIZE SHAPEHEADER]
  727. mov eax,[esi+SHAPEHEADER.xmin-SIZE SHAPEHEADER]
  728. mov tempXmax,ecx ; Store Xmax and Xmin
  729. mov tempXmin,eax
  730. mov ecx,[esi+SHAPEHEADER.ymax-SIZE SHAPEHEADER]
  731. mov eax,[esi+SHAPEHEADER.ymin-SIZE SHAPEHEADER]
  732. sub ecx,eax ; ecx = Height of sprite
  733. add eax,edx ; eax = top line
  734. inc ecx ; Add one line
  735. nop
  736. ;
  737. ; Now check for lines off the top of the clipping window
  738. ;
  739. cmp eax,ebx
  740. jl ClippedTop
  741. ;
  742. ; Now check for lines off the bottom of the clipping window
  743. ;
  744. rw5:
  745. lea ebx,[eax+ecx-1] ; ebx=Last Line
  746. nop
  747. sub ebx,paneY1 ; Check to see if off bottom
  748. ja ClippedBottom
  749. rw6:
  750. mov lines,ecx ; eax still equals top line
  751. ;
  752. ; Now check clipping in X
  753. ;
  754. mov ebx,tempXmax
  755. mov ecx,tempXmin
  756. mov edx,paneX0
  757. sub ebx,ecx ; ebx = Width of sprite
  758. add ecx,hotX ; ecx = offset to left edge
  759. cmp ecx,edx ; Is sprite off left edge of screen?
  760. jl ClippedLeft
  761. lea edx,[ebx+ecx-1]
  762. mov edi,[edi+WINDOW.buffer] ; edi points to top left of buffer
  763. sub edx,paneX1
  764. jnb ClippedRight
  765. ;
  766. ; Work out screen position
  767. ;
  768. //NowDraw:
  769. imul DestWidth
  770. add eax,ecx
  771. xor ecx,ecx
  772. add edi,eax
  773. mov StartofLine,edi
  774. push ebp
  775. mov ebp,lookaside
  776. xor ebx,ebx
  777. nop
  778. ;
  779. ; Main drawing loop
  780. ;
  781. ;
  782. lineLoop:
  783. mov al,[esi]
  784. inc esi
  785. shr al,1
  786. ja RunPacket
  787. jnz StringPacket
  788. jnc EndPacket
  789. //SkipPacket:
  790. xor ecx,ecx
  791. mov cl,[esi]
  792. inc esi
  793. add edi,ecx
  794. jmp lineLoop
  795. RunPacket:
  796. xor ecx,ecx
  797. mov cl,[esi]
  798. inc esi
  799. mov cl,[ecx+ebp]
  800. rp1:
  801. mov [edi],cl
  802. inc edi
  803. dec al
  804. jnz rp1
  805. jmp lineLoop
  806. StringPacket:
  807. //
  808. // 17 cycles / 8 bytes - 2.125 per byte
  809. //
  810. sub al,8
  811. jc sp2
  812. sp1:
  813. mov cl,[esi]
  814. mov bl,[esi+4]
  815. mov cl,[ecx+ebp]
  816. mov bl,[ebx+ebp]
  817. mov [edi],cl
  818. mov [edi+4],bl
  819. mov cl,[esi+1]
  820. mov bl,[esi+5]
  821. mov cl,[ecx+ebp]
  822. mov bl,[ebx+ebp]
  823. mov [edi+1],cl
  824. mov [edi+5],bl
  825. mov cl,[esi+2]
  826. mov bl,[esi+6]
  827. mov cl,[ecx+ebp]
  828. mov bl,[ebx+ebp]
  829. mov [edi+2],cl
  830. mov [edi+6],bl
  831. mov cl,[esi+3]
  832. mov bl,[esi+7]
  833. add esi,8
  834. add edi,8
  835. mov cl,[ecx+ebp]
  836. mov bl,[ebx+ebp]
  837. mov [edi+3-8],cl
  838. mov [edi+7-8],bl
  839. sub al,8
  840. jnc sp1
  841. sp2:
  842. add al,8
  843. jz lineLoop
  844. sp3:
  845. xor ecx,ecx
  846. mov cl,[esi]
  847. mov cl,[ecx+ebp]
  848. inc esi
  849. mov [edi],cl
  850. inc edi
  851. dec al
  852. jnz sp3
  853. jmp lineLoop
  854. EndPacket:
  855. mov edx,DestWidth
  856. mov edi,StartofLine
  857. add edi,edx
  858. mov edx,lines
  859. dec edx
  860. mov StartofLine,edi
  861. mov lines,edx
  862. jnz lineLoop
  863. pop ebp
  864. jmp Exit
  865. ;
  866. ;
  867. ; Lines are clipped off the bottom of the clip window
  868. ;
  869. ;
  870. ClippedBottom:
  871. sub ecx,ebx ; Remove lines that go off bottom
  872. jbe Exit
  873. jmp rw6
  874. ;
  875. ;
  876. ; Lines are off the top of the clip window
  877. ;
  878. ;
  879. ClippedTop:
  880. sub ebx,eax ; ebx=Lines to skip
  881. xor eax,eax
  882. sub ecx,ebx ; ecx=Lines in sprite
  883. jbe Exit ; Off top of screen
  884. rw8:
  885. mov al,[esi]
  886. add esi,2
  887. shr al,1
  888. ja rw8
  889. jnz rw8StringPacket ; Skip over lines in sprite data
  890. jc rw8
  891. dec esi
  892. dec ebx
  893. jnz rw8
  894. mov eax,paneY0 ; eax=top line
  895. jmp rw5
  896. rw8StringPacket:
  897. lea esi,[esi+eax-1]
  898. jmp rw8
  899. ;
  900. ;
  901. ; Sprite is clipped on either left or right
  902. ;
  903. ;
  904. ClippedLeft:
  905. sub edx,ecx
  906. mov edi,[edi+WINDOW.buffer] ; edi points to top left of buffer
  907. cmp ebx,edx
  908. jbe Exit ; Completly off left of screen?
  909. jmp ClippedX
  910. ClippedRight:
  911. cmp ecx,edx ; Completly off right of screen?
  912. jbe Exit
  913. ClippedX:
  914. imul DestWidth
  915. add edi,eax
  916. mov eax,paneX0
  917. mov edx,paneX1
  918. add eax,edi
  919. add edx,edi ; eax=Last pixel on right edge of clip window
  920. mov StartofClip,eax
  921. mov EndofClip,edx
  922. add edi,ecx
  923. xor ecx,ecx
  924. mov StartofLine,edi
  925. push ebp
  926. mov ebp,lookaside
  927. ;
  928. ; Clipped left and/or right drawing loop
  929. ;
  930. clineLoop:
  931. mov al,[esi]
  932. inc esi
  933. shr al,1
  934. ja cRunPacket
  935. jnz cStringPacket
  936. jnc cEndPacket
  937. //cSkipPacket:
  938. xor ecx,ecx
  939. mov cl,[esi]
  940. inc esi
  941. add edi,ecx
  942. //DEBUG
  943. push edi
  944. shr edi,28
  945. cmp edi,8
  946. pop edi
  947. je clineLoop
  948. //END DEBUG
  949. jmp assertError //clineLoop
  950. cRunPacket:
  951. mov cl,[esi]
  952. inc esi
  953. crp1:
  954. cmp edi,StartofClip
  955. jc crp2
  956. cmp edi,EndofClip
  957. jnbe clineLoop
  958. mov cl,[ecx+ebp]
  959. mov [edi],cl
  960. crp2:
  961. inc edi
  962. dec al
  963. jnz crp1
  964. jmp clineLoop
  965. cStringPacket:
  966. mov cl,[esi]
  967. inc esi
  968. cmp edi,StartofClip
  969. jc crp3
  970. cmp edi,EndofClip
  971. jnbe crp3a
  972. mov cl,[ecx+ebp]
  973. mov [edi],cl
  974. crp3:
  975. inc edi
  976. dec al
  977. jnz cStringPacket
  978. jmp clineLoop
  979. crp3a:
  980. and eax,255
  981. lea esi,[esi+eax-1]
  982. jmp clineLoop
  983. cEndPacket:
  984. mov edx,DestWidth
  985. mov eax,EndofClip
  986. add eax,edx
  987. mov edi,StartofLine
  988. mov EndofClip,eax
  989. nop
  990. mov eax,StartofClip
  991. add edi,edx
  992. add eax,edx
  993. mov edx,lines
  994. mov StartofLine,edi
  995. dec edx
  996. mov StartofClip,eax
  997. mov lines,edx
  998. jnz clineLoop
  999. pop ebp
  1000. jmp Exit
  1001. //
  1002. //
  1003. // Same routine as above, but with Alpha Table effects
  1004. //
  1005. //
  1006. AlphaDraw:
  1007. mov edi,pane
  1008. nop
  1009. ;
  1010. ; Clip left and right of clipping window
  1011. ;
  1012. mov ecx,[edi+PANE.x0]
  1013. mov edx,[edi+PANE.y0]
  1014. mov ebx,ecx
  1015. mov eax,edx
  1016. sar ebx,31
  1017. xor eax,-1
  1018. sar eax,31 ; If less than 0, make 0
  1019. xor ebx,-1
  1020. and ecx,ebx
  1021. and edx,eax
  1022. mov paneX0,ecx
  1023. mov paneY0,edx
  1024. ;
  1025. ; Clip top and bottom of clipping window
  1026. ;
  1027. mov ecx,[edi+PANE.x1]
  1028. mov edx,[edi+PANE.y1]
  1029. mov edi,[edi+PANE.window]
  1030. mov esi,shape_table
  1031. mov eax,[edi+WINDOW.x_max]
  1032. xor ebx,ebx
  1033. inc eax
  1034. nop
  1035. sub ecx,eax
  1036. mov DestWidth,eax
  1037. setge bl
  1038. dec ebx ; if ecx is less than eax, load ecx with eax
  1039. nop
  1040. and ecx,ebx
  1041. mov ebx,[edi+WINDOW.y_max]
  1042. add ecx,eax
  1043. inc ebx
  1044. xor eax,eax
  1045. sub edx,ebx
  1046. setge al
  1047. dec eax
  1048. mov paneX1,ecx
  1049. and edx,eax
  1050. mov eax,shape_number
  1051. add edx,ebx
  1052. mov ebx,paneY0
  1053. ;
  1054. ; paneX0,Y0 to PaneX1,Y1 are 0,0 -> 639,479 or window size to render too
  1055. ;
  1056. mov ecx,[esi+eax*8+8] ; ESI now points to start of sprite data
  1057. mov paneY1,edx
  1058. lea esi,[esi+ecx+SIZE SHAPEHEADER]
  1059. mov edx,hotY
  1060. mov ecx,[esi+SHAPEHEADER.xmax-SIZE SHAPEHEADER]
  1061. mov eax,[esi+SHAPEHEADER.xmin-SIZE SHAPEHEADER]
  1062. mov tempXmax,ecx ; Store Xmax and Xmin
  1063. mov tempXmin,eax
  1064. mov ecx,[esi+SHAPEHEADER.ymax-SIZE SHAPEHEADER]
  1065. mov eax,[esi+SHAPEHEADER.ymin-SIZE SHAPEHEADER]
  1066. sub ecx,eax ; ecx = Height of sprite
  1067. add eax,edx ; eax = top line
  1068. inc ecx ; Add one line
  1069. nop
  1070. ;
  1071. ; Now check for lines off the top of the clipping window
  1072. ;
  1073. cmp eax,ebx
  1074. jl aClippedTop
  1075. ;
  1076. ; Now check for lines off the bottom of the clipping window
  1077. ;
  1078. arw5:
  1079. lea ebx,[eax+ecx-1] ; ebx=Last Line
  1080. nop
  1081. sub ebx,paneY1 ; Check to see if off bottom
  1082. ja aClippedBottom
  1083. //arw6:
  1084. mov lines,ecx ; eax still equals top line
  1085. ;
  1086. ; Now check clipping in X
  1087. ;
  1088. mov ebx,tempXmax
  1089. mov ecx,tempXmin
  1090. mov edx,paneX0
  1091. sub ebx,ecx ; ebx = Width of sprite
  1092. add ecx,hotX ; ecx = offset to left edge
  1093. cmp ecx,edx ; Is sprite off left edge of screen?
  1094. jl aClippedLeft
  1095. lea edx,[ebx+ecx-1]
  1096. mov edi,[edi+WINDOW.buffer] ; edi points to top left of buffer
  1097. sub edx,paneX1
  1098. jnbe aClippedRight
  1099. ;
  1100. ; Work out screen position
  1101. ;
  1102. //aNowDraw:
  1103. imul DestWidth
  1104. add eax,ecx
  1105. xor ecx,ecx
  1106. add edi,eax
  1107. mov StartofLine,edi
  1108. push ebp
  1109. mov ebp,lookaside
  1110. xor ebx,ebx
  1111. nop
  1112. ;
  1113. ; Main drawing loop
  1114. ;
  1115. ;
  1116. alineLoop:
  1117. mov al,[esi]
  1118. inc esi
  1119. shr al,1
  1120. ja aRunPacket
  1121. jnz aStringPacket
  1122. jnc aEndPacket
  1123. //aSkipPacket:
  1124. xor ecx,ecx
  1125. mov cl,[esi]
  1126. inc esi
  1127. add edi,ecx
  1128. jmp alineLoop
  1129. aRunPacket:
  1130. xor ecx,ecx
  1131. mov cl,[esi]
  1132. inc esi
  1133. mov ch,[ecx+ebp]
  1134. arp1:
  1135. mov cl,[edi]
  1136. inc edi
  1137. mov cl,AlphaTable[ecx]
  1138. dec al
  1139. mov [edi-1],cl
  1140. jnz arp1
  1141. jmp alineLoop
  1142. aStringPacket:
  1143. xor ecx,ecx
  1144. mov cl,[esi]
  1145. mov ch,[ecx+ebp]
  1146. inc esi
  1147. mov cl,[edi]
  1148. inc edi
  1149. mov cl,AlphaTable[ecx]
  1150. dec al
  1151. mov [edi-1],cl
  1152. jnz aStringPacket
  1153. jmp alineLoop
  1154. aEndPacket:
  1155. mov edx,DestWidth
  1156. mov edi,StartofLine
  1157. add edi,edx
  1158. mov edx,lines
  1159. dec edx
  1160. mov StartofLine,edi
  1161. mov lines,edx
  1162. jnz alineLoop
  1163. pop ebp
  1164. jmp Exit
  1165. ;
  1166. ;
  1167. ; Lines are clipped off the bottom of the clip window
  1168. ;
  1169. ;
  1170. aClippedBottom:
  1171. sub ecx,ebx ; Remove lines that go off bottom
  1172. jbe Exit
  1173. jmp rw6
  1174. ;
  1175. ;
  1176. ; Lines are off the top of the clip window
  1177. ;
  1178. ;
  1179. aClippedTop:
  1180. sub ebx,eax ; ebx=Lines to skip
  1181. xor eax,eax
  1182. sub ecx,ebx ; ecx=Lines in sprite
  1183. jbe Exit ; Off top of screen
  1184. arw8:
  1185. mov al,[esi]
  1186. add esi,2
  1187. shr al,1
  1188. ja arw8
  1189. jnz arw8StringPacket ; Skip over lines in sprite data
  1190. jc arw8
  1191. dec esi
  1192. dec ebx
  1193. jnz arw8
  1194. mov eax,paneY0 ; eax=top line
  1195. jmp arw5
  1196. arw8StringPacket:
  1197. lea esi,[esi+eax-1]
  1198. jmp arw8
  1199. ;
  1200. ;
  1201. ; Sprite is clipped on either left or right
  1202. ;
  1203. ;
  1204. aClippedLeft:
  1205. sub edx,ecx
  1206. mov edi,[edi+WINDOW.buffer] ; edi points to top left of buffer
  1207. cmp ebx,edx
  1208. jbe Exit ; Completly off left of screen?
  1209. jmp aClippedX
  1210. aClippedRight:
  1211. cmp ecx,edx ; Completly off right of screen?
  1212. jbe Exit
  1213. aClippedX:
  1214. imul DestWidth
  1215. add edi,eax
  1216. mov eax,paneX0
  1217. mov edx,paneX1
  1218. add eax,edi
  1219. add edx,edi ; eax=Last pixel on right edge of clip window
  1220. mov StartofClip,eax
  1221. mov EndofClip,edx
  1222. add edi,ecx
  1223. xor ecx,ecx
  1224. mov StartofLine,edi
  1225. push ebp
  1226. mov ebp,lookaside
  1227. ;
  1228. ; Clipped left and/or right drawing loop
  1229. ;
  1230. aclineLoop:
  1231. mov al,[esi]
  1232. inc esi
  1233. shr al,1
  1234. ja acRunPacket
  1235. jnz acStringPacket
  1236. jnc acEndPacket
  1237. //acSkipPacket:
  1238. xor ecx,ecx
  1239. mov cl,[esi]
  1240. inc esi
  1241. add edi,ecx
  1242. jmp aclineLoop
  1243. acRunPacket:
  1244. xor ecx,ecx
  1245. mov cl,[esi]
  1246. inc esi
  1247. mov ch,[ecx+ebp]
  1248. acrp1:
  1249. cmp edi,StartofClip
  1250. jc acrp2
  1251. cmp edi,EndofClip
  1252. jnbe aclineLoop
  1253. mov cl,[edi]
  1254. mov cl,AlphaTable[ecx]
  1255. mov [edi],cl
  1256. acrp2:
  1257. inc edi
  1258. dec al
  1259. jnz acrp1
  1260. jmp aclineLoop
  1261. acStringPacket:
  1262. xor ecx,ecx
  1263. mov cl,[esi]
  1264. inc esi
  1265. cmp edi,StartofClip
  1266. jc acrp3
  1267. cmp edi,EndofClip
  1268. jnbe acrp3a
  1269. mov ch,[ecx+ebp]
  1270. mov cl,[edi]
  1271. mov cl,AlphaTable[ecx]
  1272. mov [edi],cl
  1273. acrp3:
  1274. inc edi
  1275. dec al
  1276. jnz acStringPacket
  1277. jmp aclineLoop
  1278. acrp3a:
  1279. and eax,255
  1280. lea esi,[esi+eax-1]
  1281. jmp aclineLoop
  1282. acEndPacket:
  1283. mov edx,DestWidth
  1284. mov eax,EndofClip
  1285. add eax,edx
  1286. mov edi,StartofLine
  1287. mov EndofClip,eax
  1288. nop
  1289. mov eax,StartofClip
  1290. add edi,edx
  1291. add eax,edx
  1292. mov edx,lines
  1293. mov StartofLine,edi
  1294. dec edx
  1295. mov StartofClip,eax
  1296. mov lines,edx
  1297. jnz aclineLoop
  1298. pop ebp
  1299. jmp Exit
  1300. assertError:
  1301. pop ebp
  1302. #ifdef CATCH_VFX_BUG
  1303. mov saveEdi,edi
  1304. }
  1305. //void *shape_table,LONG shape_number, LONG hotX, LONG hotY
  1306. char msg[1024];
  1307. //-------------------------------------
  1308. // Save off the shape data table start
  1309. char *shapeTable = (char *)shape_table;
  1310. char version[5];
  1311. for (long i=0;i<4;i++)
  1312. {
  1313. version[i] = *shapeTable;
  1314. shapeTable++;
  1315. }
  1316. version[4] = 0;
  1317. long numShapes = (long)*shapeTable;
  1318. shapeTable += 4;
  1319. shapeTable += (shape_number * 8);
  1320. long shapeNumOffset = (long) *shapeTable;
  1321. sprintf(msg,"SP: %08x SF: %d X: %d Y:%d V: %s SN: %d SOf: %d",shape_table,shape_number,hotX,hotY,version,numShapes,shapeNumOffset);
  1322. Fatal(saveEdi,msg);
  1323. #else
  1324. }
  1325. #endif
  1326. __asm
  1327. {
  1328. Exit:
  1329. }
  1330. }