vfx_transform.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401
  1. #include "vfx.h"
  2. extern char AlphaTable[256*256];
  3. extern enum { CPU_UNKNOWN, CPU_PENTIUM, CPU_MMX } Processor;
  4. extern void memfill(void *Dest,int Length);
  5. extern void memclear(void *Dest,int Length);
  6. void CopySprite( PANE *pane, void *texture, int X, int Y, int Width, int Height, int Flip, int Shrink );
  7. void AG_shape_fill (PANE *pane, void *shape_table,LONG shape_number, LONG hotX, LONG hotY);
  8. void AG_shape_draw (PANE *pane, void *shape_table,LONG shape_number, LONG hotX, LONG hotY);
  9. void AG_shape_translate_fill (PANE *pane, void *shape_table,LONG shape_number, LONG hotX, LONG hotY);
  10. extern unsigned int lookaside;
  11. int SqrtCount=0;
  12. typedef unsigned int DWORD;
  13. typedef struct
  14. {
  15. DWORD bounds;
  16. DWORD origin;
  17. DWORD xmin;
  18. DWORD ymin;
  19. DWORD xmax;
  20. DWORD ymax;
  21. } SHAPEHEADER;
  22. //
  23. // Sprite format
  24. //
  25. //
  26. // Marker.
  27. // 0 End of line
  28. // 1 Skip next bytes
  29. // Bit 0 = 0 Repeat next byte [7654321] times
  30. // Bit 0 = 1 String packet [7654321] bytes
  31. //
  32. static unsigned int SourceWidth,tWidth,tHeight,DestWidth; // Used for code optimizing
  33. static _int64 xmask=-1;
  34. static unsigned int tempXmax,tempXmin;
  35. static unsigned int minX,minY,maxY,maxX,SkipLeft,NewWidth,StartofLine,StartofClip,EndofClip;
  36. static unsigned int lines,paneX0,paneX1,paneY0,paneY1,SourcePointer,DestPointer;
  37. static signed int X,Y,X1;
  38. static PANE tempPANE;
  39. static WINDOW tempWINDOW;
  40. void AG_shape_transform( PANE *globalPane, void *shapeTable, LONG frameNum, LONG hotX, LONG hotY, void *tempBuffer, LONG reverse, LONG scaleUp )
  41. {
  42. _asm{
  43. mov esi,shapeTable
  44. mov eax,frameNum
  45. mov ecx,[esi+eax*8+8]
  46. mov eax,[esi+ecx+SHAPEHEADER.xmax]
  47. mov ebx,[esi+ecx+SHAPEHEADER.xmin]
  48. mov X1,eax
  49. mov X,ebx
  50. sub eax,ebx
  51. inc eax
  52. mov maxX,eax
  53. mov eax,[esi+ecx+SHAPEHEADER.ymax]
  54. mov ebx,[esi+ecx+SHAPEHEADER.ymin]
  55. mov Y,ebx
  56. sub eax,ebx
  57. inc eax
  58. mov maxY,eax
  59. }
  60. tempWINDOW.buffer=(UBYTE*)tempBuffer;
  61. tempWINDOW.x_max=maxX-1;
  62. tempWINDOW.y_max=maxY-1;
  63. tempPANE.window=&tempWINDOW;
  64. tempPANE.x0=0;
  65. tempPANE.y0=0;
  66. tempPANE.x1=maxX-1;
  67. tempPANE.y1=maxY-1;
  68. //-------------------------------------------------------------------------------------
  69. // Some armor here. We have still have a bug somewhere that trashes the shape by
  70. // the time it gets here. Armor against for now and make Fatal to try to track down!
  71. #define MAX_X 360
  72. #define MAX_Y 360
  73. if ((maxX * maxY) >= (MAX_Y * MAX_X))
  74. {
  75. return;
  76. }
  77. //-------------------------------------------------------------------------------------
  78. memclear(tempBuffer,maxX*maxY);
  79. AG_shape_draw ( &tempPANE, shapeTable, frameNum, -X, -Y );
  80. if(scaleUp)
  81. {
  82. if(reverse)
  83. CopySprite( globalPane, tempBuffer, hotX-X1, hotY+Y, maxX, maxY, reverse, scaleUp );
  84. else
  85. CopySprite( globalPane, tempBuffer, hotX+X, hotY+Y, maxX, maxY, reverse, scaleUp );
  86. }
  87. else
  88. {
  89. if(reverse)
  90. CopySprite( globalPane, tempBuffer, hotX-(X1>>1), hotY+(Y>>1), maxX, maxY, reverse, scaleUp );
  91. else
  92. CopySprite( globalPane, tempBuffer, hotX+(X>>1), hotY+(Y>>1), maxX, maxY, reverse, scaleUp );
  93. }
  94. }
  95. void AG_shape_translate_transform( PANE *globalPane, void *shapeTable, LONG frameNum, LONG hotX, LONG hotY,void *tempBuffer, LONG reverse, LONG scaleUp )
  96. {
  97. _asm{
  98. mov esi,shapeTable
  99. mov eax,frameNum
  100. mov ecx,[esi+eax*8+8]
  101. mov eax,[esi+ecx+SHAPEHEADER.xmax]
  102. mov ebx,[esi+ecx+SHAPEHEADER.xmin]
  103. mov X1,eax
  104. mov X,ebx
  105. sub eax,ebx
  106. inc eax
  107. mov maxX,eax
  108. mov eax,[esi+ecx+SHAPEHEADER.ymax]
  109. mov ebx,[esi+ecx+SHAPEHEADER.ymin]
  110. mov Y,ebx
  111. sub eax,ebx
  112. inc eax
  113. mov maxY,eax
  114. }
  115. tempWINDOW.buffer=(UBYTE*)tempBuffer;
  116. tempWINDOW.x_max=maxX-1;
  117. tempWINDOW.y_max=maxY-1;
  118. tempPANE.window=&tempWINDOW;
  119. tempPANE.x0=0;
  120. tempPANE.y0=0;
  121. tempPANE.x1=maxX-1;
  122. tempPANE.y1=maxY-1;
  123. //-------------------------------------------------------------------------------------
  124. // Some armor here. We have still have a bug somewhere that trashes the shape by
  125. // the time it gets here. Armor against for now and make Fatal to try to track down!
  126. #define MAX_X 360
  127. #define MAX_Y 360
  128. if ((maxX * maxY) >= (MAX_Y * MAX_X))
  129. {
  130. return;
  131. }
  132. //-------------------------------------------------------------------------------------
  133. memclear(tempBuffer,maxX*maxY);
  134. AG_shape_translate_fill ( &tempPANE, shapeTable, frameNum, -X, -Y );
  135. if(scaleUp)
  136. {
  137. if(reverse)
  138. CopySprite( globalPane, tempBuffer, hotX-X1, hotY+Y, maxX, maxY, reverse, scaleUp );
  139. else
  140. CopySprite( globalPane, tempBuffer, hotX+X, hotY+Y, maxX, maxY, reverse, scaleUp );
  141. }
  142. else
  143. {
  144. if(reverse)
  145. CopySprite( globalPane, tempBuffer, hotX-(X1>>1), hotY+(Y>>1), maxX, maxY, reverse, scaleUp );
  146. else
  147. CopySprite( globalPane, tempBuffer, hotX+(X>>1), hotY+(Y>>1), maxX, maxY, reverse, scaleUp );
  148. }
  149. }
  150. void CopySprite( PANE *pane, void *texture, int X, int Y, int Width, int Height, int Flip, int ScaleUp )
  151. {
  152. DestWidth = pane->window->x_max+1;
  153. long paneX0 = (pane->x0 < 0) ? 0 : pane->x0;
  154. long paneY0 = (pane->y0 < 0) ? 0 : pane->y0;
  155. long paneX1 = (pane->x1 >= (long)DestWidth) ? pane->window->x_max : pane->x1;
  156. long paneY1 = (pane->y1 >= (pane->window->y_max+1)) ? pane->window->y_max : pane->y1;
  157. X+=paneX0;
  158. Y+=paneY0;
  159. SourcePointer = (unsigned int)texture;
  160. SourceWidth=Width;
  161. if( X<paneX0 )
  162. {
  163. if( ScaleUp )
  164. {
  165. Width-=paneX0-X;
  166. if(Flip) // Zoomed IN
  167. SourcePointer-=paneX0-X;
  168. else
  169. SourcePointer+=paneX0-X;
  170. }
  171. else
  172. {
  173. Width-=(paneX0-X)*2;
  174. if(Flip) // Zoomed OUT
  175. SourcePointer-=(paneX0-X)*2;
  176. else
  177. SourcePointer+=(paneX0-X)*2;
  178. }
  179. X=paneX0;
  180. }
  181. if( Y<paneY0 )
  182. {
  183. if( ScaleUp )
  184. {
  185. Height-=paneY0-Y;
  186. SourcePointer+=(paneY0-Y)*Width;
  187. Y=paneY0;
  188. }
  189. else
  190. {
  191. Height-=(paneY0-Y)*2;
  192. SourcePointer+=((paneY0-Y)*2)*Width;
  193. Y=paneY0;
  194. }
  195. }
  196. if( ScaleUp )
  197. {
  198. if( X+Width > (paneX1+1) )
  199. {
  200. Width= paneX1+1-X;
  201. }
  202. }
  203. else
  204. {
  205. if( X+(Width>>1) > (paneX1+1) )
  206. {
  207. Width= (paneX1+1-X)<<1;
  208. }
  209. }
  210. if( ScaleUp )
  211. {
  212. if( Y+Height > (paneY1+1) )
  213. Height= paneY1+1-Y;
  214. }
  215. else
  216. {
  217. if( Y+(Height>>1) > (paneY1+1) )
  218. Height= (paneY1+1-Y)<<1;
  219. }
  220. if ( ( X >= paneX1 ) ||
  221. ( Y >= paneY1 ) ||
  222. ( X <= (paneX0 - Width)) ||
  223. ( Y <= (paneY0 - Height)) ||
  224. (Width<=0) ||
  225. (Height<=0))
  226. return;
  227. DestPointer = (unsigned int)pane->window->buffer + X + Y*DestWidth;
  228. tWidth=Width;
  229. tHeight=Height;
  230. _asm{
  231. push ebp
  232. mov eax,Flip
  233. mov ebx,ScaleUp
  234. test eax,eax
  235. jnz DoFlip
  236. test ebx,ebx
  237. jnz UnFlipNormal
  238. ;
  239. ; Not Flipped, Shrunk
  240. ;
  241. mov ebx,tHeight
  242. mov edi,DestPointer
  243. mov esi,SourcePointer
  244. mov ebp,tWidth
  245. shr ebx,1
  246. jz Done
  247. shr ebp,1
  248. jz Done
  249. xor eax,eax
  250. mov edx,ebp
  251. tl0:
  252. mov al,[edi]
  253. inc edi
  254. mov ah,[esi]
  255. add esi,2
  256. mov cl,AlphaTable[eax]
  257. dec ebp
  258. mov [edi-1],cl
  259. jnz tl0
  260. mov ecx,DestWidth
  261. sub esi,edx
  262. sub esi,edx
  263. add edi,ecx
  264. sub edi,edx
  265. mov ecx,SourceWidth
  266. mov ebp,edx
  267. dec ebx
  268. lea esi,[esi+ecx*2]
  269. jnz tl0
  270. jmp Done
  271. ;
  272. ; Not flipped, not shrunk
  273. ;
  274. UnFlipNormal:
  275. mov edi,DestPointer
  276. mov esi,SourcePointer
  277. mov ebx,tHeight
  278. mov ebp,tWidth
  279. xor eax,eax
  280. mov edx,ebp
  281. tl1:
  282. mov al,[edi]
  283. inc edi
  284. mov ah,[esi]
  285. inc esi
  286. cmp ah,0
  287. je SKIPME1
  288. //mov cl,AlphaTable[eax]
  289. mov [edi-1],ah
  290. SKIPME1:
  291. dec ebp
  292. jnz tl1
  293. mov ecx,DestWidth
  294. sub edi,edx
  295. add edi,ecx
  296. mov ebp,edx
  297. sub esi,edx
  298. mov ecx,SourceWidth
  299. add esi,ecx
  300. dec ebx
  301. jnz tl1
  302. jmp Done
  303. DoFlip:
  304. test ebx,ebx
  305. jnz FlipNormal
  306. ;
  307. ; Flipped, Shrunk
  308. ;
  309. mov ebp,tWidth
  310. mov ebx,tHeight
  311. shr ebp,1
  312. jz Done
  313. shr ebx,1
  314. jz Done
  315. mov eax,SourceWidth
  316. mov esi,SourcePointer
  317. mov edi,DestPointer
  318. mov edx,ebp
  319. lea esi,[esi+eax*2-1]
  320. xor eax,eax
  321. tl2:
  322. mov al,[edi]
  323. inc edi
  324. mov ah,[esi]
  325. sub esi,2
  326. mov cl,AlphaTable[eax]
  327. dec ebp
  328. mov [edi-1],cl
  329. jnz tl2
  330. mov ecx,DestWidth
  331. mov ebp,edx
  332. add esi,edx
  333. add edi,ecx
  334. add esi,edx
  335. mov ecx,SourceWidth
  336. sub edi,edx
  337. dec ebx
  338. lea esi,[esi+ecx*2]
  339. jnz tl2
  340. jmp Done
  341. ;
  342. ; Flipped, not shrunk
  343. ;
  344. FlipNormal:
  345. mov eax,SourceWidth
  346. mov esi,SourcePointer
  347. mov edi,DestPointer
  348. mov ebp,tWidth
  349. mov ebx,tHeight
  350. lea esi,[esi+eax-1]
  351. xor eax,eax
  352. mov edx,ebp
  353. tl3:
  354. mov al,[edi]
  355. inc edi
  356. mov ah,[esi]
  357. dec esi
  358. cmp ah, 0
  359. je SKIPME2
  360. //mov cl,AlphaTable[eax]
  361. mov [edi-1],ah
  362. SKIPME2:
  363. dec ebp
  364. jnz tl3
  365. sub edi,edx
  366. mov ecx,DestWidth
  367. mov ebp,edx
  368. add edi,ecx
  369. mov ecx,SourceWidth
  370. add esi,edx
  371. add esi,ecx
  372. dec ebx
  373. jnz tl3
  374. done:
  375. pop ebp
  376. }
  377. return;
  378. }
  379. /*
  380. ;
  381. ; int cdecl VFX_shape_draw (PANE *panep, void *shape_table,
  382. ; long shape_number,int hotX, int hotY)
  383. ;
  384. ; This function clips and draws a shape to a pane.
  385. ;
  386. ; The panep parameter specifies the pane.
  387. ;
  388. ; The shape parameter specifies the shape, which must be in VFX Shape format.
  389. ;
  390. ; The hotX and hotY parameters specify the location where the shape is to be
  391. ; drawn. The shape's hot spot will end up at the specified location.
  392. ;
  393. */
  394. void AG_shape_fill (PANE *pane, void *shape_table,LONG shape_number, LONG hotX, LONG hotY)
  395. {
  396. _asm{
  397. mov edi,pane
  398. nop
  399. ;
  400. ; Clip left and right of clipping window
  401. ;
  402. mov ecx,[edi+PANE.x0]
  403. mov edx,[edi+PANE.y0]
  404. mov ebx,ecx
  405. mov eax,edx
  406. sar ebx,31
  407. xor eax,-1
  408. sar eax,31 ; If less than 0, make 0
  409. xor ebx,-1
  410. and ecx,ebx
  411. and edx,eax
  412. mov paneX0,ecx
  413. mov paneY0,edx
  414. ;
  415. ; Clip top and bottom of clipping window
  416. ;
  417. mov ecx,[edi+PANE.x1]
  418. mov edx,[edi+PANE.y1]
  419. mov edi,[edi+PANE.window]
  420. mov esi,shape_table
  421. mov eax,[edi+WINDOW.x_max]
  422. xor ebx,ebx
  423. inc eax
  424. nop
  425. sub ecx,eax
  426. mov DestWidth,eax
  427. setge bl
  428. dec ebx ; if ecx is less than eax, load ecx with eax
  429. nop
  430. and ecx,ebx
  431. mov ebx,[edi+WINDOW.y_max]
  432. add ecx,eax
  433. inc ebx
  434. xor eax,eax
  435. sub edx,ebx
  436. setge al
  437. dec eax
  438. mov paneX1,ecx
  439. and edx,eax
  440. mov eax,shape_number
  441. add edx,ebx
  442. mov ebx,paneY0
  443. ;
  444. ; paneX0,Y0 to PaneX1,Y1 are 0,0 -> 639,479 or window size to render too
  445. ;
  446. mov ecx,[esi+eax*8+8] ; ESI now points to start of sprite data
  447. mov paneY1,edx
  448. lea esi,[esi+ecx+SIZE SHAPEHEADER]
  449. mov edx,hotY
  450. mov ecx,[esi+SHAPEHEADER.xmax-SIZE SHAPEHEADER]
  451. mov eax,[esi+SHAPEHEADER.xmin-SIZE SHAPEHEADER]
  452. mov tempXmax,ecx ; Store Xmax and Xmin
  453. mov tempXmin,eax
  454. mov ecx,[esi+SHAPEHEADER.ymax-SIZE SHAPEHEADER]
  455. mov eax,[esi+SHAPEHEADER.ymin-SIZE SHAPEHEADER]
  456. sub ecx,eax ; ecx = Height of sprite
  457. add eax,edx ; eax = top line
  458. inc ecx ; Add one line
  459. nop
  460. ;
  461. ; Now check for lines off the top of the clipping window
  462. ;
  463. cmp eax,ebx
  464. jl ClippedTop
  465. ;
  466. ; Now check for lines off the bottom of the clipping window
  467. ;
  468. rw5:
  469. lea ebx,[eax+ecx-1] ; ebx=Last Line
  470. nop
  471. sub ebx,paneY1 ; Check to see if off bottom
  472. ja ClippedBottom
  473. rw6:
  474. mov lines,ecx ; eax still equals top line
  475. ;
  476. ; Now check clipping in X
  477. ;
  478. mov ebx,tempXmax
  479. mov ecx,tempXmin
  480. mov edx,paneX0
  481. sub ebx,ecx ; ebx = Width of sprite
  482. add ecx,hotX ; ecx = offset to left edge
  483. cmp ecx,edx ; Is sprite off left edge of screen?
  484. jl ClippedLeft
  485. lea edx,[ebx+ecx-1]
  486. mov edi,[edi+WINDOW.buffer] ; edi points to top left of buffer
  487. sub edx,paneX1
  488. jnbe ClippedRight
  489. ;
  490. ; Work out screen position
  491. ;
  492. //NowDraw:
  493. imul DestWidth
  494. add eax,ecx
  495. xor ecx,ecx
  496. add edi,eax
  497. mov StartofLine,edi
  498. ;
  499. ;
  500. ; Main drawing loop
  501. ;
  502. ;
  503. lineLoop:
  504. mov al,[esi]
  505. inc esi
  506. shr al,1
  507. ja RunPacket
  508. jnz StringPacket
  509. jnc EndPacket
  510. //SkipPacket:
  511. xor ecx,ecx
  512. mov al,[esi]
  513. inc esi
  514. xor cl,cl
  515. rp1a:
  516. mov [edi],cl ;Fill with 0 instead of skipping
  517. inc edi
  518. dec al
  519. jnz rp1a
  520. jmp lineLoop
  521. jmp RunPacket ; Alignement problem with rp1 otherwise
  522. RunPacket:
  523. mov cl,[esi]
  524. inc esi
  525. rp1:
  526. mov [edi],cl
  527. inc edi
  528. dec al
  529. jnz rp1
  530. jmp lineLoop
  531. StringPacket:
  532. //
  533. // 17 cycles / 8 bytes - 2.125 per byte
  534. //
  535. sub al,8
  536. jc sp2
  537. sp1:
  538. mov ecx,[esi]
  539. mov ebx,[esi+4]
  540. mov [edi],ecx
  541. mov [edi+4],ebx
  542. add esi,8
  543. add edi,8
  544. sub al,8
  545. jnc sp1
  546. sp2:
  547. add al,8
  548. jz lineLoop
  549. sp3:
  550. mov cl,[esi]
  551. inc esi
  552. mov [edi],cl
  553. inc edi
  554. dec al
  555. jnz sp3
  556. jmp lineLoop
  557. EndPacket:
  558. mov edx,DestWidth
  559. mov edi,StartofLine
  560. add edi,edx
  561. mov edx,lines
  562. dec edx
  563. mov StartofLine,edi
  564. mov lines,edx
  565. jnz lineLoop
  566. jmp Exit
  567. ;
  568. ;
  569. ; Lines are clipped off the bottom of the clip window
  570. ;
  571. ;
  572. ClippedBottom:
  573. sub ecx,ebx ; Remove lines that go off bottom
  574. jbe Exit
  575. jmp rw6
  576. ;
  577. ;
  578. ; Lines are off the top of the clip window
  579. ;
  580. ;
  581. ClippedTop:
  582. sub ebx,eax ; ebx=Lines to skip
  583. xor eax,eax
  584. sub ecx,ebx ; ecx=Lines in sprite
  585. jbe Exit ; Off top of screen
  586. rw8:
  587. mov al,[esi]
  588. add esi,2
  589. shr al,1
  590. ja rw8
  591. jnz rw8StringPacket ; Skip over lines in sprite data
  592. jc rw8
  593. dec esi
  594. dec ebx
  595. jnz rw8
  596. mov eax,paneY0 ; eax=top line
  597. jmp rw5
  598. rw8StringPacket:
  599. lea esi,[esi+eax-1]
  600. jmp rw8
  601. ;
  602. ;
  603. ; Sprite is clipped on either left or right
  604. ;
  605. ;
  606. ClippedLeft:
  607. sub edx,ecx
  608. mov edi,[edi+WINDOW.buffer] ; edi points to top left of buffer
  609. cmp ebx,edx
  610. jbe Exit ; Completly off left of screen?
  611. jmp ClippedX
  612. ClippedRight:
  613. cmp ecx,edx ; Completly off right of screen?
  614. jbe Exit
  615. ClippedX:
  616. imul DestWidth
  617. add edi,eax
  618. mov eax,paneX0
  619. mov edx,paneX1
  620. add eax,edi
  621. add edx,edi ; eax=Last pixel on right edge of clip window
  622. mov StartofClip,eax
  623. mov EndofClip,edx
  624. add edi,ecx
  625. xor ecx,ecx
  626. mov StartofLine,edi
  627. ;
  628. ; Clipped left and/or right drawing loop
  629. ;
  630. clineLoop:
  631. mov al,[esi]
  632. inc esi
  633. shr al,1
  634. ja cRunPacket
  635. jnz cStringPacket
  636. jnc cEndPacket
  637. //cSkipPacket:
  638. xor ecx,ecx
  639. mov al,[esi]
  640. inc esi
  641. xor cl,cl
  642. crp1a:
  643. cmp edi,StartofClip
  644. jc crp2a
  645. cmp edi,EndofClip
  646. jnbe clineLoop
  647. mov [edi],cl
  648. crp2a:
  649. inc edi
  650. dec al
  651. jnz crp1a
  652. jmp clineLoop
  653. cRunPacket:
  654. mov cl,[esi]
  655. inc esi
  656. crp1:
  657. cmp edi,StartofClip
  658. jc crp2
  659. cmp edi,EndofClip
  660. jnbe clineLoop
  661. mov [edi],cl
  662. crp2:
  663. inc edi
  664. dec al
  665. jnz crp1
  666. jmp clineLoop
  667. cStringPacket:
  668. mov cl,[esi]
  669. inc esi
  670. cmp edi,StartofClip
  671. jc crp3
  672. cmp edi,EndofClip
  673. jnbe crp3a
  674. mov [edi],cl
  675. crp3:
  676. inc edi
  677. dec al
  678. jnz cStringPacket
  679. jmp clineLoop
  680. crp3a:
  681. and eax,255
  682. lea esi,[esi+eax-1]
  683. jmp clineLoop
  684. cEndPacket:
  685. mov edx,DestWidth
  686. mov eax,EndofClip
  687. add eax,edx
  688. mov edi,StartofLine
  689. mov EndofClip,eax
  690. nop
  691. mov eax,StartofClip
  692. add edi,edx
  693. add eax,edx
  694. mov edx,lines
  695. mov StartofLine,edi
  696. dec edx
  697. mov StartofClip,eax
  698. mov lines,edx
  699. jnz clineLoop
  700. Exit:
  701. }
  702. }
  703. /*
  704. ;----------------------------------------------------------------------------
  705. ;
  706. ; int cdecl VFX_shape_translate_draw (PANE *panep, void *shape_table,
  707. ; long shape_number,int hotX, int hotY)
  708. ;
  709. ; This function clips and draws a shape to a pane. It is identical to
  710. ; VFX_shape_draw(), except that each pixel written is translated through a
  711. ; 256-byte table which was specified by a prior call to VFX_shape_lookaside().
  712. ;
  713. ; The panep parameter specifies the pane.
  714. ;
  715. ; The shape parameter specifies the shape, which must be in VFX Shape format.
  716. ;
  717. ; The hotX and hotY parameters specify the location where the shape is to be
  718. ; drawn. The shape's hot spot will end up at the specified location.
  719. ;
  720. ; For more information, see the "VFX Shape Format Description".
  721. ;
  722. ; Return values:
  723. ;
  724. ; 0: OK
  725. ; -1: Bad window
  726. ; -2: Bad pane
  727. ; -3: Shape off pane
  728. ; -4: Null shape
  729. ;
  730. ;----------------------------------------------------------------------------
  731. */
  732. void AG_shape_translate_fill (PANE *pane, void *shape_table,LONG shape_number, LONG hotX, LONG hotY)
  733. {
  734. _asm{
  735. mov edi,pane
  736. nop
  737. ;
  738. ; Clip left and right of clipping window
  739. ;
  740. mov ecx,[edi+PANE.x0]
  741. mov edx,[edi+PANE.y0]
  742. mov ebx,ecx
  743. mov eax,edx
  744. sar ebx,31
  745. xor eax,-1
  746. sar eax,31 ; If less than 0, make 0
  747. xor ebx,-1
  748. and ecx,ebx
  749. and edx,eax
  750. mov paneX0,ecx
  751. mov paneY0,edx
  752. ;
  753. ; Clip top and bottom of clipping window
  754. ;
  755. mov ecx,[edi+PANE.x1]
  756. mov edx,[edi+PANE.y1]
  757. mov edi,[edi+PANE.window]
  758. mov esi,shape_table
  759. mov eax,[edi+WINDOW.x_max]
  760. xor ebx,ebx
  761. inc eax
  762. nop
  763. sub ecx,eax
  764. mov DestWidth,eax
  765. setge bl
  766. dec ebx ; if ecx is less than eax, load ecx with eax
  767. nop
  768. and ecx,ebx
  769. mov ebx,[edi+WINDOW.y_max]
  770. add ecx,eax
  771. inc ebx
  772. xor eax,eax
  773. sub edx,ebx
  774. setge al
  775. dec eax
  776. mov paneX1,ecx
  777. and edx,eax
  778. mov eax,shape_number
  779. add edx,ebx
  780. mov ebx,paneY0
  781. ;
  782. ; paneX0,Y0 to PaneX1,Y1 are 0,0 -> 639,479 or window size to render too
  783. ;
  784. mov ecx,[esi+eax*8+8] ; ESI now points to start of sprite data
  785. mov paneY1,edx
  786. lea esi,[esi+ecx+SIZE SHAPEHEADER]
  787. mov edx,hotY
  788. mov ecx,[esi+SHAPEHEADER.xmax-SIZE SHAPEHEADER]
  789. mov eax,[esi+SHAPEHEADER.xmin-SIZE SHAPEHEADER]
  790. mov tempXmax,ecx ; Store Xmax and Xmin
  791. mov tempXmin,eax
  792. mov ecx,[esi+SHAPEHEADER.ymax-SIZE SHAPEHEADER]
  793. mov eax,[esi+SHAPEHEADER.ymin-SIZE SHAPEHEADER]
  794. sub ecx,eax ; ecx = Height of sprite
  795. add eax,edx ; eax = top line
  796. inc ecx ; Add one line
  797. nop
  798. ;
  799. ; Now check for lines off the top of the clipping window
  800. ;
  801. cmp eax,ebx
  802. jl ClippedTop
  803. ;
  804. ; Now check for lines off the bottom of the clipping window
  805. ;
  806. rw5:
  807. lea ebx,[eax+ecx-1] ; ebx=Last Line
  808. nop
  809. sub ebx,paneY1 ; Check to see if off bottom
  810. ja ClippedBottom
  811. rw6:
  812. mov lines,ecx ; eax still equals top line
  813. ;
  814. ; Now check clipping in X
  815. ;
  816. mov ebx,tempXmax
  817. mov ecx,tempXmin
  818. mov edx,paneX0
  819. sub ebx,ecx ; ebx = Width of sprite
  820. add ecx,hotX ; ecx = offset to left edge
  821. cmp ecx,edx ; Is sprite off left edge of screen?
  822. jl ClippedLeft
  823. lea edx,[ebx+ecx-1]
  824. mov edi,[edi+WINDOW.buffer] ; edi points to top left of buffer
  825. sub edx,paneX1
  826. jnc ClippedRight
  827. ;
  828. ; Work out screen position
  829. ;
  830. //NowDraw:
  831. imul DestWidth
  832. add eax,ecx
  833. xor ecx,ecx
  834. add edi,eax
  835. mov StartofLine,edi
  836. push ebp
  837. mov ebp,lookaside
  838. xor ebx,ebx
  839. nop
  840. ;
  841. ; Main drawing loop
  842. ;
  843. ;
  844. lineLoop:
  845. mov al,[esi]
  846. inc esi
  847. shr al,1
  848. ja RunPacket
  849. jnz StringPacket
  850. jnc EndPacket
  851. //SkipPacket:
  852. xor ecx,ecx
  853. mov al,[esi]
  854. inc esi
  855. xor cl,cl
  856. rp1a:
  857. mov [edi],cl
  858. inc edi
  859. dec al
  860. jnz rp1a
  861. jmp lineLoop
  862. RunPacket:
  863. xor ecx,ecx
  864. mov cl,[esi]
  865. inc esi
  866. mov cl,[ecx+ebp]
  867. rp1:
  868. mov [edi],cl
  869. inc edi
  870. dec al
  871. jnz rp1
  872. jmp lineLoop
  873. StringPacket:
  874. //
  875. // 17 cycles / 8 bytes - 2.125 per byte
  876. //
  877. sub al,8
  878. jc sp2
  879. sp1:
  880. mov cl,[esi]
  881. mov bl,[esi+4]
  882. mov cl,[ecx+ebp]
  883. mov bl,[ebx+ebp]
  884. mov [edi],cl
  885. mov [edi+4],bl
  886. mov cl,[esi+1]
  887. mov bl,[esi+5]
  888. mov cl,[ecx+ebp]
  889. mov bl,[ebx+ebp]
  890. mov [edi+1],cl
  891. mov [edi+5],bl
  892. mov cl,[esi+2]
  893. mov bl,[esi+6]
  894. mov cl,[ecx+ebp]
  895. mov bl,[ebx+ebp]
  896. mov [edi+2],cl
  897. mov [edi+6],bl
  898. mov cl,[esi+3]
  899. mov bl,[esi+7]
  900. add esi,8
  901. add edi,8
  902. mov cl,[ecx+ebp]
  903. mov bl,[ebx+ebp]
  904. mov [edi+3-8],cl
  905. mov [edi+7-8],bl
  906. sub al,8
  907. jnc sp1
  908. sp2:
  909. add al,8
  910. jz lineLoop
  911. sp3:
  912. xor ecx,ecx
  913. mov cl,[esi]
  914. mov cl,[ecx+ebp]
  915. inc esi
  916. mov [edi],cl
  917. inc edi
  918. dec al
  919. jnz sp3
  920. jmp lineLoop
  921. EndPacket:
  922. mov edx,DestWidth
  923. mov edi,StartofLine
  924. add edi,edx
  925. mov edx,lines
  926. dec edx
  927. mov StartofLine,edi
  928. mov lines,edx
  929. jnz lineLoop
  930. pop ebp
  931. jmp Exit
  932. ;
  933. ;
  934. ; Lines are clipped off the bottom of the clip window
  935. ;
  936. ;
  937. ClippedBottom:
  938. sub ecx,ebx ; Remove lines that go off bottom
  939. jbe Exit
  940. jmp rw6
  941. ;
  942. ;
  943. ; Lines are off the top of the clip window
  944. ;
  945. ;
  946. ClippedTop:
  947. sub ebx,eax ; ebx=Lines to skip
  948. xor eax,eax
  949. sub ecx,ebx ; ecx=Lines in sprite
  950. jbe Exit ; Off top of screen
  951. rw8:
  952. mov al,[esi]
  953. add esi,2
  954. shr al,1
  955. ja rw8
  956. jnz rw8StringPacket ; Skip over lines in sprite data
  957. jc rw8
  958. dec esi
  959. dec ebx
  960. jnz rw8
  961. mov eax,paneY0 ; eax=top line
  962. jmp rw5
  963. rw8StringPacket:
  964. lea esi,[esi+eax-1]
  965. jmp rw8
  966. ;
  967. ;
  968. ; Sprite is clipped on either left or right
  969. ;
  970. ;
  971. ClippedLeft:
  972. sub edx,ecx
  973. mov edi,[edi+WINDOW.buffer] ; edi points to top left of buffer
  974. cmp ebx,edx
  975. jbe Exit ; Completly off left of screen?
  976. jmp ClippedX
  977. ClippedRight:
  978. cmp ecx,edx ; Completly off right of screen?
  979. jbe Exit
  980. ClippedX:
  981. imul DestWidth
  982. add edi,eax
  983. mov eax,paneX0
  984. mov edx,paneX1
  985. add eax,edi
  986. add edx,edi ; eax=Last pixel on right edge of clip window
  987. mov StartofClip,eax
  988. mov EndofClip,edx
  989. add edi,ecx
  990. xor ecx,ecx
  991. mov StartofLine,edi
  992. push ebp
  993. mov ebp,lookaside
  994. ;
  995. ; Clipped left and/or right drawing loop
  996. ;
  997. clineLoop:
  998. mov al,[esi]
  999. inc esi
  1000. shr al,1
  1001. ja cRunPacket
  1002. jnz cStringPacket
  1003. jnc cEndPacket
  1004. //cSkipPacket:
  1005. mov al,[esi]
  1006. inc esi
  1007. xor cl,cl
  1008. crp1a:
  1009. cmp edi,StartofClip
  1010. jc crp2a
  1011. cmp edi,EndofClip
  1012. jnc clineLoop
  1013. mov [edi],cl
  1014. crp2a:
  1015. inc edi
  1016. dec al
  1017. jnz crp1a
  1018. jmp clineLoop
  1019. cRunPacket:
  1020. mov cl,[esi]
  1021. inc esi
  1022. crp1:
  1023. cmp edi,StartofClip
  1024. jc crp2
  1025. cmp edi,EndofClip
  1026. jnc clineLoop
  1027. mov cl,[ecx+ebp]
  1028. mov [edi],cl
  1029. crp2:
  1030. inc edi
  1031. dec al
  1032. jnz crp1
  1033. jmp clineLoop
  1034. cStringPacket:
  1035. mov cl,[esi]
  1036. inc esi
  1037. cmp edi,StartofClip
  1038. jc crp3
  1039. cmp edi,EndofClip
  1040. jnc crp3a
  1041. mov cl,[ecx+ebp]
  1042. mov [edi],cl
  1043. crp3:
  1044. inc edi
  1045. dec al
  1046. jnz cStringPacket
  1047. jmp clineLoop
  1048. crp3a:
  1049. and eax,255
  1050. lea esi,[esi+eax-1]
  1051. jmp clineLoop
  1052. cEndPacket:
  1053. mov edx,DestWidth
  1054. mov eax,EndofClip
  1055. add eax,edx
  1056. mov edi,StartofLine
  1057. mov EndofClip,eax
  1058. nop
  1059. mov eax,StartofClip
  1060. add edi,edx
  1061. add eax,edx
  1062. mov edx,lines
  1063. mov StartofLine,edi
  1064. dec edx
  1065. mov StartofClip,eax
  1066. mov lines,edx
  1067. jnz clineLoop
  1068. pop ebp
  1069. Exit:
  1070. }
  1071. }