vfxtile.cpp 82 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008
  1. //-----------------------------------------------------------
  2. //
  3. // FASA Interactive Technologies
  4. //
  5. // VFX Tile Draw Routine
  6. //
  7. // Started April 30, 1996
  8. // FFS
  9. //
  10. //-----------------------------------------------------------
  11. //-----------------------------------------------------------
  12. // Include Files
  13. #ifndef DSTD_H
  14. #include "dstd.h"
  15. #endif
  16. #ifndef VFX_H
  17. #include "vfx.h"
  18. #endif
  19. static unsigned long pwXMax,count; // Must be static for assembly optimizations
  20. static unsigned char *FadeTable; // Must be static for assembly optimizations
  21. //-----------------------------------------------------------
  22. struct tileStruct
  23. {
  24. byte tileHotSpotX;
  25. byte tileHotSpotY;
  26. byte numScanLines;
  27. byte numScanColumns;
  28. };
  29. //-----------------------------------------------------------
  30. struct newShapeStruct
  31. {
  32. long header;
  33. short tileHotSpotX;
  34. short tileHotSpotY;
  35. short numScanLines;
  36. short numScanColumns;
  37. };
  38. #define FULLY_CLIPPED 0xCDCF0001
  39. #define FORMAT_SPEC 0xFEEDABBA
  40. #define BLACK 0x10101010
  41. //-----------------------------------------------------------
  42. // This one is called if the cameraScale is 100. No drop
  43. // of any pixels. Straight BLT to screen.
  44. long VFX_nTile_draw (PANE* pane, void *tile, LONG hotX, LONG hotY, MemoryPtr fadeTable)
  45. {
  46. //-----------------------------------------
  47. // Format of tile shape data is NEW!!
  48. // Byte -- Hot Spot X.
  49. // Byte -- Hot Spot Y.
  50. // Byte -- NumScanLines. (height)
  51. // Byte -- NumScanColumns. (width)
  52. // Word -- One word for each scanline indicating offset into main data for that scanline.
  53. // Bytes -- Main Shape data. Each scanline pointed to by above table.
  54. // The main difference between .fsx and .gsx files are in the main data.
  55. // Because there is no end scanline marker, the length of each Blt can be
  56. // determined and a MUCH faster rep movsd can be used to Blt the data.
  57. //------------------------------------------------------
  58. //-------------------------------------------------------
  59. // Create Important Data from tile data.
  60. MemoryPtr tileData = (MemoryPtr)tile + sizeof(tileStruct);
  61. tileStruct *tileInfo = (tileStruct *)tile;
  62. unsigned long *yOffsetTable = (unsigned long *)(tileData);
  63. pwXMax = pane->window->x_max+1;
  64. long paneX0 = (pane->x0 < 0) ? 0 : pane->x0;
  65. long paneY0 = (pane->y0 < 0) ? 0 : pane->y0;
  66. long paneX1 = (pane->x1 >= (long)pwXMax) ? pane->window->x_max : pane->x1;
  67. long paneY1 = (pane->y1 >= (pane->window->y_max+1)) ? pane->window->y_max : pane->y1;
  68. long scanLines = tileInfo->numScanLines;
  69. long scanCol = tileInfo->numScanColumns;
  70. long topLeftX = (hotX + paneX0) - tileInfo->tileHotSpotX;
  71. long topLeftY = (hotY + paneY0) - tileInfo->tileHotSpotY; //In theory, tileHotSpotY is always zero!
  72. if ( (topLeftX >= paneX1) ||
  73. (topLeftY >= paneY1) ||
  74. (topLeftX <= (paneX0 - scanCol)) ||
  75. (topLeftY <= (paneY0 - scanLines)))
  76. return(FULLY_CLIPPED);
  77. MemoryPtr screenBuffer = pane->window->buffer + ((topLeftY > paneY0) ? topLeftY*pwXMax : paneY0*pwXMax);
  78. long firstScanOffset = (topLeftY < paneY0) ? paneY0 - topLeftY : 0;
  79. long lastScanOffset = ((topLeftY + scanLines) > paneY1) ? paneY1 - topLeftY + 1 : scanLines;
  80. yOffsetTable += firstScanOffset;
  81. if( (topLeftX>paneX0) && ((topLeftX+scanCol) < paneX1) )
  82. {
  83. FadeTable=fadeTable;
  84. screenBuffer+=topLeftX;
  85. count=lastScanOffset-firstScanOffset;
  86. //
  87. // No clipping, whole tile is on screen
  88. //
  89. _asm{
  90. push ebp
  91. mov edx,screenBuffer
  92. mov esi,tile
  93. mov ebp,yOffsetTable
  94. mov eax,FadeTable
  95. add esi,[ebp]
  96. cmp eax,-1
  97. jz DoBlack
  98. test eax,eax
  99. jnz DoFade
  100. //
  101. // Normal
  102. //
  103. DisplayTile:
  104. xor ebx,ebx
  105. mov eax,[ebp+4]
  106. mov ecx,[ebp]
  107. lea ebp,[ebp+4]
  108. sub eax,ecx
  109. mov bl,[esi]
  110. mov ecx,0
  111. jz DisplayTile1
  112. lea edi,[ebx+edx]
  113. dec eax
  114. sub ecx,edi
  115. inc esi
  116. and ecx,3
  117. sub eax,ecx
  118. jle DisplayTile2
  119. rep movsb
  120. mov ecx,eax
  121. and eax,3 ; Main loop, copying an unclipped tile
  122. shr ecx,2
  123. jz DisplayTile2
  124. DisplayTile3:
  125. mov ebx,[esi]
  126. add esi,4
  127. mov [edi],ebx
  128. add edi,4
  129. dec ecx
  130. jnz DisplayTile3
  131. DisplayTile2:
  132. add eax,ecx
  133. jz DisplayTile1
  134. DisplayTile4:
  135. mov bl,[esi]
  136. inc esi
  137. mov [edi],bl
  138. inc edi
  139. dec eax
  140. jnz DisplayTile4
  141. DisplayTile1:
  142. mov ebx,pwXMax
  143. mov eax,count
  144. add edx,ebx
  145. dec eax
  146. mov count,eax
  147. jnz DisplayTile
  148. jmp done
  149. //
  150. // Black
  151. //
  152. DoBlack: xor ebx,ebx
  153. mov eax,[ebp+4]
  154. mov ecx,[ebp]
  155. lea ebp,[ebp+4]
  156. sub eax,ecx
  157. mov bl,[esi]
  158. mov ecx,0
  159. jz DoBlack1
  160. lea edi,[ebx+edx]
  161. dec eax
  162. sub ecx,edi
  163. lea esi,[esi+eax+1]
  164. and ecx,3
  165. mov ebx,eax
  166. mov eax,BLACK
  167. sub ebx,ecx
  168. jle DoBlack2
  169. rep stosb
  170. mov ecx,ebx
  171. and ebx,3 ; Main loop, blacking out an unclipped tile
  172. shr ecx,2
  173. rep stosd
  174. DoBlack2: add ecx,ebx
  175. rep stosb
  176. DoBlack1: mov ebx,pwXMax
  177. mov eax,count
  178. add edx,ebx
  179. dec eax
  180. mov count,eax
  181. jnz DoBlack
  182. jmp done
  183. //
  184. // Fade
  185. //
  186. DoFade: xor ebx,ebx
  187. mov ecx,[ebp+4]
  188. mov eax,[ebp]
  189. lea ebp,[ebp+4]
  190. sub ecx,eax
  191. mov bl,[esi]
  192. lea ecx,[ecx-1]
  193. jz DoFade1
  194. lea edi,[ebx+edx]
  195. inc esi
  196. // Fade inner loop
  197. push edx
  198. mov edx,FadeTable
  199. mov bl,[esi]
  200. inc esi
  201. DoFade0: inc edi
  202. dec ecx
  203. mov al,[edx+ebx]
  204. mov bl,[esi]
  205. mov [edi-1],al
  206. lea esi,[esi+1]
  207. jnz DoFade0
  208. pop edx
  209. dec esi
  210. DoFade1: mov ebx,pwXMax
  211. mov eax,count
  212. add edx,ebx
  213. dec eax
  214. mov count,eax
  215. jnz Dofade
  216. done:
  217. pop ebp
  218. }
  219. }
  220. else
  221. //
  222. // This tile needs to be clipped
  223. //
  224. {
  225. unsigned long currentOffset = *yOffsetTable++;
  226. unsigned long nextOffset=*yOffsetTable++;
  227. for (long scanLine = firstScanOffset; scanLine<lastScanOffset; scanLine++)
  228. {
  229. __asm
  230. {
  231. mov esi, tile
  232. xor ebx, ebx
  233. add esi, currentOffset
  234. xor eax, eax
  235. mov al, BYTE PTR [esi]
  236. inc esi
  237. add eax, topLeftX
  238. mov edi, screenBuffer
  239. add edi, eax
  240. mov ecx, nextOffset
  241. sub ecx, currentOffset
  242. xor edx, edx
  243. dec ecx
  244. mov edx, eax
  245. add edx, ecx
  246. cmp eax, paneX0
  247. jge SHORT LINE207
  248. mov ebx, paneX0
  249. sub ebx, eax
  250. add esi, ebx
  251. add edi, ebx
  252. LINE207:
  253. cmp edx, paneX1
  254. jle SHORT LINE214
  255. sub edx, paneX1
  256. dec edx
  257. jmp SHORT LEAVE_EDX
  258. LINE214:
  259. xor edx, edx
  260. LEAVE_EDX:
  261. sub ecx, ebx
  262. sub ecx, edx
  263. cmp ecx, 0
  264. jle SHORT NO_DRAW
  265. mov eax,fadeTable
  266. cmp eax,-1
  267. jz SHORT BLT_BLACK
  268. test eax,eax
  269. jz BLT_FAST
  270. //FADE_BLT_TOP:
  271. xor edx, edx
  272. mov ebx,fadeTable
  273. mov dl, [esi]
  274. inc esi
  275. Blt_fade1:
  276. inc edi
  277. dec ecx
  278. mov al, [edx+ebx]
  279. mov dl, [esi]
  280. mov BYTE PTR [edi-1], al
  281. lea esi,[esi+1]
  282. jnz Blt_fade1
  283. jmp short NO_DRAW
  284. BLT_BLACK:
  285. mov ebx,ecx ; DWORD align edi when possible
  286. sub ecx,edi
  287. mov eax,BLACK
  288. sub ecx,ebx
  289. and ecx,3
  290. sub ebx,ecx
  291. jle blt_black1
  292. rep stosb
  293. mov ecx,ebx
  294. and ebx,3
  295. shr ecx,2
  296. rep stosd
  297. blt_black1: add ecx,ebx
  298. rep stosb
  299. jmp SHORT NO_DRAW
  300. BLT_FAST:
  301. mov eax,ecx ; DWORD align edi when possible
  302. sub ecx,edi
  303. sub ecx,eax
  304. and ecx,3
  305. sub eax,ecx
  306. jle blt_fast1
  307. rep movsb
  308. mov ecx,eax
  309. and eax,3
  310. shr ecx,2
  311. rep movsd
  312. blt_fast1: add ecx,eax
  313. rep movsb
  314. NO_DRAW:
  315. }
  316. screenBuffer += pwXMax;
  317. currentOffset = nextOffset;
  318. nextOffset = *yOffsetTable++;
  319. }
  320. }
  321. //-----------------------------------------------------------
  322. return(0x00);
  323. }
  324. //----------------------------------------------------------------------------
  325. //
  326. // long VFX_shape_origin(void *shape_table, LONG shape_number);
  327. //
  328. // Returns hotspot of the shape (in pixels) relative to the upper left bounds).
  329. // (E)AX=x E(AX)=y.
  330. //
  331. //----------------------------------------------------------------------------
  332. long VFX_shape_origin(void *shape_table, LONG shape_number)
  333. {
  334. long result = -1;
  335. __asm
  336. {
  337. mov esi,shape_table
  338. add esi,8 //skip to offsets
  339. mov eax,shape_number //point to shape offset ptr
  340. shl eax,3 //mul eax by sizeof 2 longs
  341. add esi,eax
  342. mov esi,[esi] //get shape offset ptr
  343. add esi,shape_table //add base address
  344. mov eax,[esi+4] //SHAPEHEADER.origin
  345. mov result,eax
  346. }
  347. return result;
  348. }
  349. //----------------------------------------------------------------------------
  350. //
  351. // long VFX_shape_resolution(void *shape_table, LONG shape_number);
  352. //
  353. // Returns x,y resolution (image size) in pixels. (E)AX=x E(AX)=y.
  354. //
  355. //----------------------------------------------------------------------------
  356. long VFX_shape_resolution(void *shape_table, LONG shape_number)
  357. {
  358. long result = 0;
  359. __asm
  360. {
  361. mov esi,shape_table
  362. add esi,8 //skip to offsets
  363. mov eax,shape_number //point to shape offset ptr
  364. shl eax,3 //mul eax by sizeof 2 longs
  365. add esi,eax
  366. mov esi,[esi] //get shape offset ptr
  367. add esi,shape_table //add base address
  368. mov eax,[esi+16] //SHAPEHEADER.xmax ;eax = xmax - xmin
  369. sub eax,[esi+8] //SHAPEHEADER.xmin
  370. inc eax // + 1
  371. mov ebx,[esi+20] //SHAPEHEADER.ymax ;ebx = ymax - ymin
  372. sub ebx,[esi+12] //SHAPEHEADER.ymin
  373. inc ebx // + 1
  374. shl eax,16
  375. and eax,0xffff0000
  376. add eax,ebx
  377. mov result,eax
  378. }
  379. return result;
  380. }
  381. //----------------------------------------------------------------------------
  382. //
  383. // long VFX_shape_minxy(void *shape_table, LONG shape_number);
  384. //
  385. // Returns min x,min y in pixels. (E)AX=x E(AX)=y.
  386. //
  387. //---------------------------------------------------------------------------
  388. long VFX_shape_minxy(void *shape_table, LONG shape_number)
  389. {
  390. long result = 0;
  391. __asm
  392. {
  393. mov esi,shape_table
  394. add esi,8 //skip to offsets
  395. mov eax,shape_number //point to shape offset ptr
  396. shl eax,3 //mul eax by sizeof 2 longs
  397. add esi,eax
  398. mov esi,[esi] //get shape offset ptr
  399. add esi,shape_table //add base address
  400. mov eax,[esi+8] //SHAPEHEADER.xmin
  401. shl eax,16
  402. mov ebx,[esi+12] //SHAPEHEADER.ymin
  403. and eax,0xffff0000
  404. add eax,ebx
  405. mov result, eax
  406. }
  407. return result;
  408. }
  409. //;----------------------------------------------------------------------------
  410. //;
  411. //; long VFX_shape_bounds(void *shape_table, LONG shape_number);
  412. //;
  413. //; Returns width,height of the shape (including transparent areas) in pixels. (E)AX=x E(AX)=y.
  414. //; (E)AX=x E(AX)=y.
  415. //;
  416. //;----------------------------------------------------------------------------
  417. long VFX_shape_bounds (void *shape_table, long shape_number)
  418. {
  419. long boundsResult = -1;
  420. __asm
  421. {
  422. mov esi,shape_table
  423. add esi,8 //skip to offsets
  424. mov eax,shape_number //point to shape offset ptr
  425. shl eax,3 //mul eax by sizeof 2 longs
  426. add esi,eax
  427. mov esi,[esi] //get shape offset ptr
  428. add esi,shape_table //add base address
  429. mov eax,[esi] //Bounds is First Member of struct
  430. mov boundsResult, eax
  431. }
  432. return boundsResult;
  433. }
  434. //;----------------------------------------------------------------------------
  435. //;
  436. //; long VFX_shape_count(void *shape_table);
  437. //;
  438. //; Returns number of shapes references in the specified shape table. Each
  439. //; shape may have one or more references.
  440. //;
  441. //;----------------------------------------------------------------------------
  442. long VFX_shape_count (void *shape_table)
  443. {
  444. long countResult = 0;
  445. __asm
  446. {
  447. mov esi,shape_table
  448. mov eax,[esi+4]
  449. mov countResult,eax
  450. }
  451. return countResult;
  452. }
  453. //;----------------------------------------------------------------------------
  454. //;
  455. //; int cdecl VFX_line_draw (PANE *panep, int x0, int y0, int x1, int y1,
  456. //; int mode, int parm);
  457. //;
  458. //; This function clips and draws a line to a pane.
  459. //;
  460. //; The panep parameter specifies the pane.
  461. //;
  462. //; The x0 and y0 parameters specify the initial endpoint of the line.
  463. //; The x1 and y1 parameters specify the final endpoint of the line.
  464. //;
  465. //; The mode parameter specifies the operation to perform on each point
  466. //; in the line.
  467. //;
  468. //; If mode is... parm specifies...
  469. //;
  470. //; DRAW a color
  471. //; TRANSLATE the address of a color translation table
  472. //; EXECUTE the address of a caller-provided function
  473. //;
  474. //; If mode is DRAW (0), the line is drawn in a solid color specified by
  475. //; parm.
  476. //;
  477. //; If mode is TRANSLATE (1), the line is drawn with color translation.
  478. //; Each pixel along the path of the line is replaced with the correspond-
  479. //; ing entry in the color translation table specified by parm.
  480. //;
  481. //; If mode is EXECUTE (2), the line is drawn with the aid of a callback
  482. //; function specifed by parm. For each point on the line, VFX_line_draw()
  483. //; executes the callback function, passing it the coordinates of the point.
  484. //;
  485. //; The callback function must use cdecl parameter passing, and its para-
  486. //; meter list must be (int x, int y). The function's return type is not
  487. //; important; VFX_line_draw() ignores the return value (if any).
  488. //;
  489. //; VFX_line_draw() clips the line to the pane. The locus of the clipped
  490. //; line is the same for all modes and is guaranteed to be identical to the
  491. //; intersection of the loci of the unclipped line and the pane. Moreover,
  492. //; plotting always proceeds from (x0,y0) to (x1,y1) regardless of the
  493. //; relative orientation of the two points.
  494. //;
  495. //; The locus of the clipped line consists of all points in the pane whose
  496. //; minor-axis distance* from the ideal line is less than or equal to 1/2,
  497. //; with the following exception. In places where the ideal line passes
  498. //; exactly halfway between two pixels which share the same major-axis co-
  499. //; ordinate, only one of the two points is plotted. The selection method
  500. //; is unspecified, but is consistent throughout the line.
  501. //;
  502. //; * The minor-axis distance from a point P to a line L is the absolute
  503. //; difference between the minor-axis coordinates of P and Q where Q is
  504. //; the point on L having the same major-axis coordinate as P. (Here,
  505. //; major-axis and minor axis are determined by L. The major axis is
  506. //; the axis in which the endpoints of L differ the most. Likewise the
  507. //; minor-axis is the one in which the endpoints differ the least).
  508. //;
  509. //; VFX_line_draw is reentrant, so callback functions can use it.
  510. //;
  511. //;
  512. //; Examples:
  513. //;
  514. //; #define HELIOTROPE 147
  515. //; UBYTE color_negative[256];
  516. //; void cdecl DrawDiamond (int x, int y);
  517. //;
  518. //; VFX_line_draw (pane, Px, Py, Qx, Qy, DRAW, HELIOTROPE);
  519. //; draws a line from (Px,Py) to (Qx,Qy) using the color HELIOTROPE.
  520. //;
  521. //; VFX_line_draw (pane, Px, Py, Qx, Qy, TRANSLATE, (int) color_negative);
  522. //; draws a line from (Px,Py) to (Qx,Qy) replacing each pixel with its
  523. //; color negative (as specified by the table color_negative).
  524. //;
  525. //; VFX_line_draw (pane, Px, Py, Qx, Qy, EXECUTE, (int) DrawDiamond);
  526. //; draws a line of diamonds from (Px,Py) to (Qx,Qy) using the
  527. //; caller-provided function DrawDiamond().
  528. //;
  529. //; Return values:
  530. //;
  531. //; -2: pane was malformed or completely outside its window
  532. //; -1: window was malformed
  533. //; 0: all of the line was inside the pane and was drawn without clipping
  534. //; 1: some of the line was inside the pane and was drawn after clipping
  535. //; 2: the line was completely outside the pane and was not drawn
  536. //;
  537. //;----------------------------------------------------------------------------
  538. LONG VFX_line_draw (PANE *panep, LONG x0, LONG y0,
  539. LONG x1, LONG y1, LONG mode, LONG parm)
  540. {
  541. long _dx, absdx, sgndx;
  542. long _dy, absdy, sgndy;
  543. long sgndxdy, slope;
  544. long x0_, y0_, x1_, y1_;
  545. long clip_flags;
  546. long _L; //Leftmost pixel in Window coord.
  547. long _T; //Top
  548. long _R; //Right
  549. long _B; //Bottom
  550. MemoryPtr _A; //Base address of Clipped Pane
  551. long _W; //Width of underlying window (bytes)
  552. long _CX; //Window x coord. = Pane x coord. + CP_CX
  553. long _CY; //Window y coord. = Pane x coord. + CP_CY
  554. long lineResult;
  555. __asm
  556. {
  557. cld
  558. }
  559. //Clip Pane to Window Routine
  560. // get panep (esi)
  561. // windowp (ebx) = panep->win
  562. //ASSUME esi:PPANE
  563. //ASSUME ebx:PWIN
  564. __asm
  565. {
  566. mov esi,panep
  567. mov ebx,[esi] //This is the Window Pointer
  568. // _W = windowp->wnd_x1 + 1
  569. // if _W <= 0, return bad window
  570. mov eax,[ebx+4] //X1 Window Coord
  571. inc eax
  572. mov _W,eax
  573. jle ReturnBadWindow
  574. // ecx = Ysize = windowp->wnd_y1 + 1
  575. // if <= 0, return bad window
  576. mov eax,[ebx+8] //y1 Window Coord
  577. inc eax
  578. mov ecx,eax
  579. jle ReturnBadWindow
  580. // clip pane to window:
  581. // pane_x0 = max (pane->x0, 0)
  582. // pane_y0 = max (pane->y0, 0)
  583. // pane_x1 = min (pane->x1, _W - 1)
  584. // pane_y1 = min (pane->x1, (Ysize=ecx) - 1)
  585. mov eax,[esi+4] //x0 in Pane Coord
  586. mov _CX,eax
  587. cmp eax,0
  588. jg around1
  589. mov eax,0
  590. around1:
  591. mov _L,eax
  592. mov eax,[esi+8] //y0 in Pane Coord
  593. mov _CY,eax
  594. cmp eax,0
  595. jg around2
  596. mov eax,0
  597. around2:
  598. mov _T,eax
  599. mov eax,[esi+12] //X1 in Pane Coord
  600. mov edx,_W
  601. dec edx
  602. cmp eax,edx
  603. jl around3
  604. mov eax,edx
  605. around3:
  606. mov _R,eax
  607. mov eax,[esi+16] //y1 in Pane Coord
  608. mov edx,ecx
  609. dec edx
  610. cmp eax,edx
  611. jl around4
  612. mov eax,edx
  613. around4:
  614. mov _B,eax
  615. // exit if pane is malformed or completely off window:
  616. // if _B < &vname&_T, return bad pane
  617. // if _R < &vname&_L, return bad pane
  618. mov eax,_R
  619. cmp eax,_L
  620. jl ReturnBadPane
  621. mov eax,_B
  622. cmp eax,_T
  623. jl ReturnBadPane
  624. mov eax,[ebx] //Buffer in Window
  625. mov _A,eax
  626. jmp exit1
  627. ReturnBadWindow:
  628. mov eax,-1
  629. jmp exit1
  630. }
  631. __asm
  632. {
  633. ReturnBadPane:
  634. mov eax,-2
  635. }
  636. exit1:
  637. __asm
  638. {
  639. //Convert Quad Pane to Window
  640. mov eax,_CX
  641. add x0,eax
  642. add x1,eax
  643. mov eax,_CY
  644. add y0,eax
  645. add y1,eax
  646. // calculate dx, absdx, and sgndx
  647. mov eax,x1
  648. sub eax,x0
  649. mov _dx,eax
  650. cdq
  651. mov sgndx,edx
  652. xor eax,edx
  653. sub eax,edx
  654. mov absdx,eax
  655. // calculate dy, absdy, and sgndy
  656. mov eax,y1
  657. sub eax,y0
  658. mov _dy,eax
  659. cdq
  660. mov sgndy,edx
  661. xor eax,edx
  662. sub eax,edx
  663. mov absdy,eax
  664. // make working copies of endpoint coordinates
  665. mov eax,x0
  666. mov x0_,eax
  667. mov eax,x1
  668. mov x1_,eax
  669. mov eax,y0
  670. mov y0_,eax
  671. mov eax,y1
  672. mov y1_,eax
  673. // handle special cases -- vertical, horizontal
  674. cmp _dx,0
  675. je Vertical
  676. cmp _dy,0
  677. je Horizontal
  678. // calculate sgndxdy
  679. mov eax,sgndx
  680. xor eax,sgndy
  681. mov sgndxdy,eax
  682. // calculate slope
  683. mov edx,absdx
  684. mov ebx,absdy
  685. mov eax,0xFFFFFFFF
  686. cmp edx,ebx
  687. je slope2
  688. jl slope1
  689. xchg edx,ebx
  690. slope1:
  691. xor eax,eax
  692. div ebx
  693. slope2:
  694. mov slope,eax
  695. // clip line to pane
  696. mov clip_flags,0
  697. clip_loop:
  698. xor edx,edx
  699. // calculate clip0 (dl)
  700. mov eax,x0_
  701. sub eax,_L
  702. shl eax,1
  703. adc dl,dl
  704. mov eax,_R
  705. sub eax,x0_
  706. shl eax,1
  707. adc dl,dl
  708. mov eax,y0_
  709. sub eax,_T
  710. shl eax,1
  711. adc dl,dl
  712. mov eax,_B
  713. sub eax,y0_
  714. shl eax,1
  715. adc dl,dl
  716. // calculate clip1 (dh)
  717. mov eax,x1_
  718. sub eax,_L
  719. shl eax,1
  720. adc dh,dh
  721. mov eax,_R
  722. sub eax,x1_
  723. shl eax,1
  724. adc dh,dh
  725. mov eax,y1_
  726. sub eax,_T
  727. shl eax,1
  728. adc dh,dh
  729. mov eax,_B
  730. sub eax,y1_
  731. shl eax,1
  732. adc dh,dh
  733. // remember clip flags for final return value
  734. or clip_flags,edx
  735. // accept if line is completely in the pane
  736. or edx,edx
  737. jz Accept
  738. // reject if line is completely above, below, left of, or right of the pane
  739. test dl,dh
  740. jnz ReturnReject
  741. // dispatch to appropriate clipper
  742. mov ebx,absdx
  743. cmp ebx,absdy
  744. jl ClipYmajor
  745. //ClipXmajor:
  746. // clip (x0,y0)
  747. test dl,1000B
  748. jnz Xmaj_x0_lo
  749. test dl,0100B
  750. jnz Xmaj_x0_hi
  751. test dl,0010B
  752. jnz Xmaj_y0_lo
  753. test dl,0001B
  754. jnz Xmaj_y0_hi
  755. // clip (x1,y1)
  756. test dh,1000B
  757. jnz Xmaj_x1_lo
  758. test dh,0100B
  759. jnz Xmaj_x1_hi
  760. test dh,0010B
  761. jnz Xmaj_y1_lo
  762. test dh,0001B
  763. jnz Xmaj_y1_hi
  764. jmp clip_loop
  765. ClipYmajor:
  766. // clip (x0,y0)
  767. test dl,1000B
  768. jnz Ymaj_x0_lo
  769. test dl,0100B
  770. jnz Ymaj_x0_hi
  771. test dl,0010B
  772. jnz Ymaj_y0_lo
  773. test dl,0001B
  774. jnz Ymaj_y0_hi
  775. // clip (x1,y1)
  776. test dh,1000B
  777. jnz Ymaj_x1_lo
  778. test dh,0100B
  779. jnz Ymaj_x1_hi
  780. test dh,0010B
  781. jnz Ymaj_y1_lo
  782. test dh,0001B
  783. jnz Ymaj_y1_hi
  784. jmp clip_loop
  785. Xmaj_x0_lo:
  786. // x0_ = CP_L;
  787. // y0_ = y0 + sgndxdy * floor ((x0_-x0)*slope)+1/2);
  788. mov eax,_L
  789. mov x0_,eax
  790. sub eax,x0
  791. mul slope
  792. add eax,0x80000000
  793. adc edx,0
  794. mov eax,edx
  795. mov edx,sgndxdy
  796. xor eax,edx
  797. sub eax,edx
  798. add eax,y0
  799. mov y0_,eax
  800. jmp clip_loop
  801. Ymaj_x0_lo:
  802. // x0_ = CP_L;
  803. // y0_ = y0 + sgndxdy * ceil ((x0_-x0-1/2)/slope);
  804. mov eax, _L
  805. mov x0_, eax
  806. sub eax,x0
  807. mov edx,eax
  808. dec edx
  809. mov eax,0x80000000
  810. div slope
  811. cmp edx,1
  812. sbb eax,-1
  813. mov edx,sgndxdy
  814. xor eax,edx
  815. sub eax,edx
  816. add eax,y0
  817. mov y0_,eax
  818. jmp clip_loop
  819. Xmaj_x0_hi:
  820. // x0_ = CP_R;
  821. // y0_ = y0 - sgndxdy * floor ((x0-CP_R)*slope)+1/2);
  822. mov eax,_R
  823. mov x0_,eax
  824. sub eax,x0
  825. neg eax
  826. mul slope
  827. add eax,0x80000000
  828. adc edx,0
  829. mov eax,edx
  830. mov edx,sgndxdy
  831. not edx
  832. xor eax,edx
  833. sub eax,edx
  834. add eax,y0
  835. mov y0_,eax
  836. jmp clip_loop
  837. Ymaj_x0_hi:
  838. // x0_ = CP_R;
  839. // y0_ = y0 - sgndxdy * ceil ((x0-x0_-1/2)/slope);
  840. mov eax,_R
  841. mov x0_,eax
  842. sub eax,x0
  843. neg eax
  844. mov edx,eax
  845. dec edx
  846. mov eax,0x80000000
  847. div slope
  848. cmp edx,1
  849. sbb eax,-1
  850. mov edx,sgndxdy
  851. not edx
  852. xor eax,edx
  853. sub eax,edx
  854. add eax,y0
  855. mov y0_,eax
  856. jmp clip_loop
  857. Ymaj_y0_lo:
  858. // y0_ = CP_T;
  859. // x0_ = x0 + sgndxdy * floor ((y0_-y0)*slope)+1/2);
  860. mov eax,_T
  861. mov y0_,eax
  862. sub eax,y0
  863. mul slope
  864. add eax,0x80000000
  865. adc edx,0
  866. mov eax,edx
  867. mov edx,sgndxdy
  868. xor eax,edx
  869. sub eax,edx
  870. add eax,x0
  871. mov x0_,eax
  872. jmp clip_loop
  873. Xmaj_y0_lo:
  874. // y0_ = CP_T;
  875. // x0_ = x0 + sgndxdy * ceil ((y0_-y0-1/2)/slope);
  876. mov eax,_T
  877. mov y0_,eax
  878. sub eax,y0
  879. mov edx,eax
  880. dec edx
  881. mov eax,0x80000000
  882. div slope
  883. cmp edx,1
  884. sbb eax,-1
  885. mov edx,sgndxdy
  886. xor eax,edx
  887. sub eax,edx
  888. add eax,x0
  889. mov x0_,eax
  890. jmp clip_loop
  891. Ymaj_y0_hi:
  892. // y0_ = CP_B;
  893. // x0_ = x0 - sgndxdy * floor ((y0-y0_)*slope+1/2);
  894. mov eax,_B
  895. mov y0_,eax
  896. sub eax,y0
  897. neg eax
  898. mul slope
  899. add eax,0x80000000
  900. adc edx,0
  901. mov eax,edx
  902. mov edx,sgndxdy
  903. not edx
  904. xor eax,edx
  905. sub eax,edx
  906. add eax,x0
  907. mov x0_,eax
  908. jmp clip_loop
  909. Xmaj_y0_hi:
  910. // y0_ = CP_B;
  911. // x0_ = x0 - sgndxdy * ceil ((y0-y0_-1/2)/slope);
  912. mov eax,_B
  913. mov y0_,eax
  914. sub eax,y0
  915. neg eax
  916. mov edx,eax
  917. dec edx
  918. mov eax,0x80000000
  919. div slope
  920. cmp edx,1
  921. sbb eax,-1
  922. mov edx,sgndxdy
  923. not edx
  924. xor eax,edx
  925. sub eax,edx
  926. add eax,x0
  927. mov x0_,eax
  928. jmp clip_loop
  929. Xmaj_x1_lo:
  930. // x1_ = CP_L;
  931. // y1_ = y0 - sgndxdy * floor ((x0-x1_)*slope+1/2);
  932. mov eax,_L
  933. mov x1_,eax
  934. sub eax,x0
  935. neg eax
  936. mul slope
  937. add eax,0x80000000
  938. adc edx,0
  939. mov eax,edx
  940. mov edx,sgndxdy
  941. not edx
  942. xor eax,edx
  943. sub eax,edx
  944. add eax,y0
  945. mov y1_,eax
  946. jmp clip_loop
  947. Ymaj_x1_lo:
  948. // x1_ = CP_L;
  949. // y1_ = y0 - sgndxdy * (ceil ((x0-x1_+1/2)/slope) - 1);
  950. mov eax,_L
  951. mov x1_,eax
  952. sub eax,x0
  953. neg eax
  954. mov edx,eax
  955. mov eax,0x80000000
  956. div slope
  957. cmp edx,1
  958. sbb eax,0
  959. mov edx,sgndxdy
  960. not edx
  961. xor eax,edx
  962. sub eax,edx
  963. add eax,y0
  964. mov y1_,eax
  965. jmp clip_loop
  966. Xmaj_x1_hi:
  967. // x1_ = CP_R;
  968. // y1_ = y0 + sgndxdy * floor ((x1_-x0)*slope+1/2);
  969. mov eax,_R
  970. mov x1_,eax
  971. sub eax,x0
  972. mul slope
  973. add eax,0x80000000
  974. adc edx,0
  975. mov eax,edx
  976. mov edx,sgndxdy
  977. xor eax,edx
  978. sub eax,edx
  979. add eax,y0
  980. mov y1_,eax
  981. jmp clip_loop
  982. Ymaj_x1_hi:
  983. // x1_ = CP_R;
  984. // y1_ = y0 + sgndxdy * (ceil ((x1_-x0+1/2)/slope) - 1);
  985. mov eax,_R
  986. mov x1_,eax
  987. sub eax,x0
  988. mov edx,eax
  989. mov eax,0x80000000
  990. div slope
  991. cmp edx,1
  992. sbb eax,0
  993. mov edx,sgndxdy
  994. xor eax,edx
  995. sub eax,edx
  996. add eax,y0
  997. mov y1_,eax
  998. jmp clip_loop
  999. Ymaj_y1_lo:
  1000. // y1_ = CP_T;
  1001. // x1_ = x0 - sgndxdy * floor ((y0-y1_)*slope+1/2);
  1002. mov eax,_T
  1003. mov y1_,eax
  1004. sub eax,y0
  1005. neg eax
  1006. mul slope
  1007. add eax,0x80000000
  1008. adc edx,0
  1009. mov eax,edx
  1010. mov edx,sgndxdy
  1011. not edx
  1012. xor eax,edx
  1013. sub eax,edx
  1014. add eax,x0
  1015. mov x1_,eax
  1016. jmp clip_loop
  1017. Xmaj_y1_lo:
  1018. // y1_ = CP_T;
  1019. // x1_ = x0 - sgndxdy * (ceil ((y0-y1_+1/2)/slope) - 1);
  1020. mov eax,_T
  1021. mov y1_,eax
  1022. sub eax,y0
  1023. neg eax
  1024. mov edx,eax
  1025. mov eax,0x80000000
  1026. div slope
  1027. cmp edx,1
  1028. sbb eax,0
  1029. mov edx,sgndxdy
  1030. not edx
  1031. xor eax,edx
  1032. sub eax,edx
  1033. add eax,x0
  1034. mov x1_,eax
  1035. jmp clip_loop
  1036. Ymaj_y1_hi:
  1037. // y1_ = CP_B;
  1038. // x1_ = x0 + sgndxdy * floor ((y1_-y0)*slope+1/2);
  1039. mov eax,_B
  1040. mov y1_,eax
  1041. sub eax,y0
  1042. mul slope
  1043. add eax,0x80000000
  1044. adc edx,0
  1045. mov eax,edx
  1046. mov edx,sgndxdy
  1047. xor eax,edx
  1048. sub eax,edx
  1049. add eax,x0
  1050. mov x1_,eax
  1051. jmp clip_loop
  1052. Xmaj_y1_hi:
  1053. // y1_ = CP_B;
  1054. // x1_ = x0 + sgndxdy * (ceil ((y1_-y0+1/2)/slope) - 1);
  1055. mov eax,_B
  1056. mov y1_,eax
  1057. sub eax,y0
  1058. mov edx,eax
  1059. mov eax,0x80000000
  1060. div slope
  1061. cmp edx,1
  1062. sbb eax,0
  1063. mov edx,sgndxdy
  1064. xor eax,edx
  1065. sub eax,edx
  1066. add eax,x0
  1067. mov x1_,eax
  1068. jmp clip_loop
  1069. #if 0
  1070. //----------------------------------------------------------------------------
  1071. //
  1072. // Macros for inner loops of DRAW forms (Y major, X major, and Straight)
  1073. //
  1074. //----------------------------------------------------------------------------
  1075. YM_DRAW MACRO adc_sbb
  1076. mov [edi],al ; [adr] = pixel
  1077. add edx,ebx ; accum += slope
  1078. adc_sbb edi,esi ; adr += ystep (+ xstep)
  1079. dec ecx ; count--
  1080. ENDM
  1081. //----------------------------------------------------------------------------
  1082. XM_DRAW MACRO inc_dec
  1083. mov [edi],al ; [adr] = pixel
  1084. inc_dec edi ; adr += xstep
  1085. add edx,ebx ; accum += slope
  1086. jnc @F ; if accum overflowed,
  1087. add edi,esi ; adr += ystep
  1088. @@:
  1089. dec ecx ; count--
  1090. ENDM
  1091. //----------------------------------------------------------------------------
  1092. ST_DRAW MACRO
  1093. mov [edi],al ; [adr] = pixel
  1094. add edi,esi ; adr += xystep
  1095. dec ecx ; count--
  1096. ENDM
  1097. //----------------------------------------------------------------------------
  1098. //
  1099. // Macros for inner loops of XLAT forms (Y major, X major, and Straight)
  1100. //
  1101. //----------------------------------------------------------------------------
  1102. YM_XLAT MACRO adc_sbb
  1103. mov al,[edi] ; pixel = [adr]
  1104. xlat ; pixel = parm[pixel]
  1105. mov [edi],al ; [adr] = pixel
  1106. add edx,ebp ; accum += slope
  1107. adc_sbb edi,esi ; adr += ystep (+ xstep)
  1108. dec ecx ; count--
  1109. ENDM
  1110. //----------------------------------------------------------------------------
  1111. XM_XLAT MACRO inc_dec
  1112. mov al,[edi] ; pixel = [adr]
  1113. xlat ; pixel = parm[pixel]
  1114. mov [edi],al ; [adr] = pixel
  1115. inc_dec edi ; adr += xstep
  1116. add edx,ebp ; accum += slope
  1117. jnc @F ; if accum overflowed,
  1118. add edi,esi ; adr += ystep
  1119. @@:
  1120. dec ecx ; count--
  1121. ENDM
  1122. //----------------------------------------------------------------------------
  1123. SW_XLAT MACRO
  1124. mov al,[edi] ; pixel = [adr]
  1125. xlat ; pixel = parm[pixel]
  1126. mov [edi],al ; [adr] = pixel
  1127. add edi,esi ; adr += xystep
  1128. dec ecx ; count--
  1129. ENDM
  1130. //----------------------------------------------------------------------------
  1131. #endif
  1132. Accept:
  1133. // calculate adr (edi),
  1134. // address of first pixel = window_buffer + CP_W*y0 + x0
  1135. //GET_WINDOW_ADDRESS x0_, y0_
  1136. mov eax,y0_
  1137. imul _W
  1138. add eax,_A
  1139. add eax,x0_
  1140. mov edi,eax
  1141. // calculate ystep (esi) = CP_W * sgn (dy)
  1142. mov esi,_W
  1143. xor esi,sgndy
  1144. sub esi,sgndy
  1145. // get slope
  1146. mov ebx,slope
  1147. // branch to Diagonal, Xmajor or Ymajor depending on absdx & absdy
  1148. mov eax,absdx
  1149. cmp eax,absdy
  1150. je Diagonal
  1151. jg Xmajor
  1152. ;----------------------------------------------------------------------------
  1153. //Ymajor:
  1154. // calculate count (ecx) = abs (y1_ - y0_) + 1
  1155. mov eax,y1_
  1156. sub eax,y0_
  1157. cdq
  1158. xor eax,edx
  1159. sub eax,edx
  1160. inc eax
  1161. mov ecx,eax
  1162. // calculate accum (edx) = abs (y0_ - y0) * slope + 1/2
  1163. mov eax,y0_
  1164. sub eax,y0
  1165. cdq
  1166. xor eax,edx
  1167. sub eax,edx
  1168. mul ebx
  1169. add eax,0x80000000
  1170. mov edx,eax
  1171. // branch to YmajorNegdx or fall through to YmajorPosdx depending on sgndx
  1172. cmp sgndx,-1
  1173. je YmajorNegdx
  1174. //----------------------------------------------------------------------------
  1175. //YmajorPosdx:
  1176. cmp mode,1
  1177. je YmPdxXlat
  1178. jg YmPdxProc
  1179. //----------------------------------------------------------------------------
  1180. //YmPdxDraw:
  1181. mov eax,parm // get line color
  1182. YmPdxDrawLoop:
  1183. //REPEAT LD_COPIES-1 //; repeat this code copies-1 times or 3 times!
  1184. //YM_DRAW <adc> //; process a pixel
  1185. mov [edi],al // [adr] = pixel
  1186. add edx,ebx // accum += slope
  1187. adc edi,esi // adr += ystep (+ xstep)
  1188. dec ecx // count--
  1189. jz YmPdxDrawDone
  1190. //YM_DRAW <adc> //; process a pixel
  1191. mov [edi],al // [adr] = pixel
  1192. add edx,ebx // accum += slope
  1193. adc edi,esi // adr += ystep (+ xstep)
  1194. dec ecx // count--
  1195. jz YmPdxDrawDone
  1196. //YM_DRAW <adc> //; process a pixel
  1197. mov [edi],al // [adr] = pixel
  1198. add edx,ebx // accum += slope
  1199. adc edi,esi // adr += ystep (+ xstep)
  1200. dec ecx // count--
  1201. jz YmPdxDrawDone
  1202. //YM_DRAW <adc> //; process a pixel
  1203. mov [edi],al // [adr] = pixel
  1204. add edx,ebx // accum += slope
  1205. adc edi,esi // adr += ystep (+ xstep)
  1206. dec ecx // count--
  1207. jnz YmPdxDrawLoop //; while (count)
  1208. YmPdxDrawDone:
  1209. jmp ReturnClipFlags //; done
  1210. //----------------------------------------------------------------------------
  1211. YmPdxXlat:
  1212. mov eax,parm //; get translation table pointer
  1213. push ebp //; preserve ebp
  1214. mov ebp,ebx //; use ebp for slope to free up ebx
  1215. mov ebx,eax //; table ptr must be in ebx for xlat
  1216. YmPdxXlatLoop:
  1217. //REPEAT LD_COPIES-1 //; repeat this code copies-1 times or 3 Times
  1218. //YM_XLAT <adc> //; process a pixel
  1219. mov al,[edi] //; pixel = [adr]
  1220. xlat //; pixel = parm[pixel]
  1221. mov [edi],al //; [adr] = pixel
  1222. add edx,ebp //; accum += slope
  1223. adc edi,esi //; adr += ystep (+ xstep)
  1224. dec ecx //; count--
  1225. jz YmPdxXlatDone
  1226. //YM_XLAT <adc> //; process a pixel
  1227. mov al,[edi] //; pixel = [adr]
  1228. xlat //; pixel = parm[pixel]
  1229. mov [edi],al //; [adr] = pixel
  1230. add edx,ebp //; accum += slope
  1231. adc edi,esi //; adr += ystep (+ xstep)
  1232. dec ecx //; count--
  1233. jz YmPdxXlatDone
  1234. //YM_XLAT <adc> //; process a pixel
  1235. mov al,[edi] //; pixel = [adr]
  1236. xlat //; pixel = parm[pixel]
  1237. mov [edi],al //; [adr] = pixel
  1238. add edx,ebp //; accum += slope
  1239. adc edi,esi //; adr += ystep (+ xstep)
  1240. dec ecx //; count--
  1241. jz YmPdxXlatDone
  1242. //YM_XLAT <adc> //; process a pixel
  1243. mov al,[edi] //; pixel = [adr]
  1244. xlat //; pixel = parm[pixel]
  1245. mov [edi],al //; [adr] = pixel
  1246. add edx,ebp //; accum += slope
  1247. adc edi,esi //; adr += ystep (+ xstep)
  1248. dec ecx //; count--
  1249. jnz YmPdxXlatLoop //; while (count)
  1250. YmPdxXlatDone:
  1251. pop ebp //; restore ebp
  1252. jmp ReturnClipFlags //; done
  1253. //----------------------------------------------------------------------------
  1254. YmPdxProc:
  1255. mov esi,panep // get pane pointer
  1256. mov edi,x0_ // x (edi) = x0_ in pane coordinates
  1257. sub edi,[esi+4] //.x0
  1258. mov eax,y0_ // y (esi) = y0_ in pane coordinates
  1259. sub eax,[esi+8] //.y0
  1260. mov esi,eax
  1261. mov eax,sgndy // ybump (eax) = (sgndy=-1) ? -1 : +1
  1262. add eax,eax
  1263. inc eax
  1264. YmPdxProcLoop:
  1265. pushad // callback (x, y)
  1266. call parm
  1267. popad
  1268. add edx,ebx // accum += slope
  1269. jnc F1 // if overflow, x++
  1270. inc edi
  1271. F1:
  1272. add esi,eax // y += ybump
  1273. dec ecx // count--
  1274. jnz YmPdxProcLoop // while (count)
  1275. jmp ReturnClipFlags // done
  1276. //----------------------------------------------------------------------------
  1277. YmajorNegdx:
  1278. neg esi // neg_ystep (esi) = -ystep
  1279. cmp mode,1
  1280. je YmNdxXlat
  1281. jg YmNdxProc
  1282. //----------------------------------------------------------------------------
  1283. //YmNdxDraw:
  1284. mov eax,parm // get line color
  1285. YmNdxDrawLoop:
  1286. //REPEAT LD_COPIES-1 // repeat this code copies-1 times or 3 times
  1287. //YM_DRAW <sbb> // process a pixel
  1288. mov [edi],al //; [adr] = pixel
  1289. add edx,ebx //; accum += slope
  1290. sbb edi,esi //; adr += ystep (+ xstep)
  1291. dec ecx //; count--
  1292. jz YmNdxDrawDone
  1293. //YM_DRAW <sbb> // process a pixel
  1294. mov [edi],al //; [adr] = pixel
  1295. add edx,ebx //; accum += slope
  1296. sbb edi,esi //; adr += ystep (+ xstep)
  1297. dec ecx //; count--
  1298. jz YmNdxDrawDone
  1299. //YM_DRAW <sbb> // process a pixel
  1300. mov [edi],al //; [adr] = pixel
  1301. add edx,ebx //; accum += slope
  1302. sbb edi,esi //; adr += ystep (+ xstep)
  1303. dec ecx //; count--
  1304. jz YmNdxDrawDone
  1305. //YM_DRAW <sbb> // process a pixel
  1306. mov [edi],al //; [adr] = pixel
  1307. add edx,ebx //; accum += slope
  1308. sbb edi,esi //; adr += ystep (+ xstep)
  1309. dec ecx //; count--
  1310. jnz YmNdxDrawLoop // while (count)
  1311. YmNdxDrawDone:
  1312. jmp ReturnClipFlags // done
  1313. //----------------------------------------------------------------------------
  1314. YmNdxXlat:
  1315. mov eax,parm // get translation table pointer
  1316. push ebp // preserve ebp
  1317. mov ebp,ebx // use ebp for slope to free up ebx
  1318. mov ebx,eax // table ptr must be in ebx for xlat
  1319. YmNdxXlatLoop:
  1320. //REPEAT LD_COPIES-1 // repeat this code copies-1 times or 3 times
  1321. //YM_XLAT <sbb> // process a pixel
  1322. mov al,[edi] //; pixel = [adr]
  1323. xlat //; pixel = parm[pixel]
  1324. mov [edi],al //; [adr] = pixel
  1325. add edx,ebp //; accum += slope
  1326. sbb edi,esi //; adr += ystep (+ xstep)
  1327. dec ecx //; count--
  1328. jz YmNdxXlatDone
  1329. //YM_XLAT <sbb> // process a pixel
  1330. mov al,[edi] //; pixel = [adr]
  1331. xlat //; pixel = parm[pixel]
  1332. mov [edi],al //; [adr] = pixel
  1333. add edx,ebp //; accum += slope
  1334. sbb edi,esi //; adr += ystep (+ xstep)
  1335. dec ecx //; count--
  1336. jz YmNdxXlatDone
  1337. //YM_XLAT <sbb> // process a pixel
  1338. mov al,[edi] //; pixel = [adr]
  1339. xlat //; pixel = parm[pixel]
  1340. mov [edi],al //; [adr] = pixel
  1341. add edx,ebp //; accum += slope
  1342. sbb edi,esi //; adr += ystep (+ xstep)
  1343. dec ecx //; count--
  1344. jz YmNdxXlatDone
  1345. //YM_XLAT <sbb> // process a pixel
  1346. mov al,[edi] //; pixel = [adr]
  1347. xlat //; pixel = parm[pixel]
  1348. mov [edi],al //; [adr] = pixel
  1349. add edx,ebp //; accum += slope
  1350. sbb edi,esi //; adr += ystep (+ xstep)
  1351. dec ecx //; count--
  1352. jnz YmNdxXlatLoop // while (count)
  1353. YmNdxXlatDone:
  1354. pop ebp // restore ebp
  1355. jmp ReturnClipFlags // done
  1356. //----------------------------------------------------------------------------
  1357. YmNdxProc:
  1358. mov esi,panep // get pane pointer
  1359. mov edi,x0_ // x (edi) = x0_ in pane coordinates
  1360. sub edi,[esi+4] //.x0
  1361. mov eax,y0_ // y (esi) = y0_ in pane coordinates
  1362. sub eax,[esi+8] //.y0
  1363. mov esi,eax
  1364. mov eax,sgndy // ybump (eax) = (sgndy=-1) ? -1 : +1
  1365. add eax,eax
  1366. inc eax
  1367. YmNdxProcLoop:
  1368. pushad // callback (x, y)
  1369. call parm
  1370. popad
  1371. add edx,ebx // accum += slope
  1372. jnc F2 // if overflow, x--
  1373. dec edi
  1374. F2:
  1375. add esi,eax // y += ybump
  1376. dec ecx // count--
  1377. jnz YmNdxProcLoop // while (count)
  1378. jmp ReturnClipFlags // done
  1379. //----------------------------------------------------------------------------
  1380. Xmajor:
  1381. // calculate count (ecx) = abs (x1_ - x0_) + 1
  1382. mov eax,x1_
  1383. sub eax,x0_
  1384. cdq
  1385. xor eax,edx
  1386. sub eax,edx
  1387. inc eax
  1388. mov ecx,eax
  1389. // calculate accum (edx) = abs (x0_ - x0) * slope + 1/2
  1390. mov eax,x0_
  1391. sub eax,x0
  1392. cdq
  1393. xor eax,edx
  1394. sub eax,edx
  1395. mul ebx
  1396. add eax,0x80000000
  1397. mov edx,eax
  1398. // branch to XmajorNegdx or fall through to XmajorPosdx depending on sgndx
  1399. cmp sgndx,-1
  1400. je XmajorNegdx
  1401. //----------------------------------------------------------------------------
  1402. //XmajorPosdx:
  1403. cmp mode,1
  1404. je XmPdxXlat
  1405. jg XmPdxProc
  1406. //----------------------------------------------------------------------------
  1407. //XmPdxDraw:
  1408. mov eax,parm // get line color
  1409. XmPdxDrawLoop:
  1410. //REPEAT LD_COPIES-1 // repeat this code copies-1 times or 3 Times
  1411. //XM_DRAW <inc> // process a pixel
  1412. mov [edi],al // [adr] = pixel
  1413. inc edi // adr += xstep
  1414. add edx,ebx // accum += slope
  1415. jnc Fa1 // if accum overflowed,
  1416. add edi,esi // adr += ystep
  1417. Fa1:
  1418. dec ecx // count--
  1419. jz XmPdxDrawDone
  1420. //XM_DRAW <inc> // process a pixel
  1421. mov [edi],al // [adr] = pixel
  1422. inc edi // adr += xstep
  1423. add edx,ebx // accum += slope
  1424. jnc Fa2 // if accum overflowed,
  1425. add edi,esi // adr += ystep
  1426. Fa2:
  1427. dec ecx // count--
  1428. jz XmPdxDrawDone
  1429. //XM_DRAW <inc> // process a pixel
  1430. mov [edi],al // [adr] = pixel
  1431. inc edi // adr += xstep
  1432. add edx,ebx // accum += slope
  1433. jnc Fa3 // if accum overflowed,
  1434. add edi,esi // adr += ystep
  1435. Fa3:
  1436. dec ecx // count--
  1437. jz XmPdxDrawDone
  1438. //XM_DRAW <inc> // process a pixel
  1439. mov [edi],al // [adr] = pixel
  1440. inc edi // adr += xstep
  1441. add edx,ebx // accum += slope
  1442. jnc Fa4 // if accum overflowed,
  1443. add edi,esi // adr += ystep
  1444. Fa4:
  1445. dec ecx // count--
  1446. jnz XmPdxDrawLoop // while (count)
  1447. XmPdxDrawDone:
  1448. jmp ReturnClipFlags // done
  1449. //----------------------------------------------------------------------------
  1450. XmPdxXlat:
  1451. mov eax,parm // get translation table pointer
  1452. push ebp // preserve ebp
  1453. mov ebp,ebx // use ebp for slope to free up ebx
  1454. mov ebx,eax // table ptr must be in ebx for xlat
  1455. XmPdxXlatLoop:
  1456. //REPEAT LD_COPIES-1 // repeat this code copies-1 times or 3 times
  1457. //XM_XLAT <inc> // process a pixel
  1458. mov al,[edi] //; pixel = [adr]
  1459. xlat //; pixel = parm[pixel]
  1460. mov [edi],al //; [adr] = pixel
  1461. inc edi //; adr += xstep
  1462. add edx,ebp //; accum += slope
  1463. jnc Fb1 //; if accum overflowed,
  1464. add edi,esi //; adr += ystep
  1465. Fb1:
  1466. dec ecx //; count--
  1467. jz XmPdxXlatDone
  1468. //XM_XLAT <inc> // process a pixel
  1469. mov al,[edi] //; pixel = [adr]
  1470. xlat //; pixel = parm[pixel]
  1471. mov [edi],al //; [adr] = pixel
  1472. inc edi //; adr += xstep
  1473. add edx,ebp //; accum += slope
  1474. jnc Fb2 //; if accum overflowed,
  1475. add edi,esi //; adr += ystep
  1476. Fb2:
  1477. dec ecx //; count--
  1478. jz XmPdxXlatDone
  1479. //XM_XLAT <inc> // process a pixel
  1480. mov al,[edi] //; pixel = [adr]
  1481. xlat //; pixel = parm[pixel]
  1482. mov [edi],al //; [adr] = pixel
  1483. inc edi //; adr += xstep
  1484. add edx,ebp //; accum += slope
  1485. jnc Fb3 //; if accum overflowed,
  1486. add edi,esi //; adr += ystep
  1487. Fb3:
  1488. dec ecx //; count--
  1489. jz XmPdxXlatDone
  1490. //XM_XLAT <inc> // process a pixel
  1491. mov al,[edi] //; pixel = [adr]
  1492. xlat //; pixel = parm[pixel]
  1493. mov [edi],al //; [adr] = pixel
  1494. inc edi //; adr += xstep
  1495. add edx,ebp //; accum += slope
  1496. jnc Fb4 //; if accum overflowed,
  1497. add edi,esi //; adr += ystep
  1498. Fb4:
  1499. dec ecx //; count--
  1500. jnz XmPdxXlatLoop // while (count)
  1501. XmPdxXlatDone:
  1502. pop ebp // restore ebp
  1503. jmp ReturnClipFlags // done
  1504. //----------------------------------------------------------------------------
  1505. XmPdxProc:
  1506. mov esi,panep // get pane pointer
  1507. mov edi,x0_ // x (edi) = x0_ in pane coordinates
  1508. sub edi,[esi+4] //.x0
  1509. mov eax,y0_ // y (esi) = y0_ in pane coordinates
  1510. sub eax,[esi+8] //.y0
  1511. mov esi,eax
  1512. mov eax,sgndy // xbump (eax) = (sgndy=-1) ? -1 : +1
  1513. add eax,eax
  1514. inc eax
  1515. XmPdxProcLoop:
  1516. pushad // callback (x, y)
  1517. call parm
  1518. popad
  1519. add edx,ebx // accum += slope
  1520. jnc F3 // if overflow, y++
  1521. inc esi
  1522. F3: add edi,eax // x += xbump
  1523. dec ecx // count--
  1524. jnz XmPdxProcLoop // while (count)
  1525. jmp ReturnClipFlags // done
  1526. //----------------------------------------------------------------------------
  1527. XmajorNegdx:
  1528. cmp mode,1
  1529. je XmNdxXlat
  1530. jg XmNdxProc
  1531. //----------------------------------------------------------------------------
  1532. //XmNdxDraw:
  1533. mov eax,parm // get line color
  1534. XmNdxDrawLoop:
  1535. //REPEAT LD_COPIES-1 // repeat this code copies-1 times or 3 times
  1536. //XM_DRAW <dec> // process a pixel
  1537. mov [edi],al //; [adr] = pixel
  1538. dec edi //; adr += xstep
  1539. add edx,ebx //; accum += slope
  1540. jnc Fc1 //; if accum overflowed,
  1541. add edi,esi //; adr += ystep
  1542. Fc1:
  1543. dec ecx //; count--
  1544. jz XmNdxDrawDone
  1545. //XM_DRAW <dec> // process a pixel
  1546. mov [edi],al //; [adr] = pixel
  1547. dec edi //; adr += xstep
  1548. add edx,ebx //; accum += slope
  1549. jnc Fc2 //; if accum overflowed,
  1550. add edi,esi //; adr += ystep
  1551. Fc2:
  1552. dec ecx //; count--
  1553. jz XmNdxDrawDone
  1554. //XM_DRAW <dec> // process a pixel
  1555. mov [edi],al //; [adr] = pixel
  1556. dec edi //; adr += xstep
  1557. add edx,ebx //; accum += slope
  1558. jnc Fc3 //; if accum overflowed,
  1559. add edi,esi //; adr += ystep
  1560. Fc3:
  1561. dec ecx //; count--
  1562. jz XmNdxDrawDone
  1563. //XM_DRAW <dec> // process a pixel
  1564. mov [edi],al //; [adr] = pixel
  1565. dec edi //; adr += xstep
  1566. add edx,ebx //; accum += slope
  1567. jnc Fc4 //; if accum overflowed,
  1568. add edi,esi //; adr += ystep
  1569. Fc4:
  1570. dec ecx //; count--
  1571. jnz XmNdxDrawLoop // while (count)
  1572. XmNdxDrawDone:
  1573. jmp ReturnClipFlags // done
  1574. //----------------------------------------------------------------------------
  1575. XmNdxXlat:
  1576. mov eax,parm // get translation table pointer
  1577. push ebp // preserve ebp
  1578. mov ebp,ebx // use ebp for slope to free up ebx
  1579. mov ebx,eax // table ptr must be in ebx for xlat
  1580. XmNdxXlatLoop:
  1581. //REPEAT LD_COPIES-1 // repeat this code copies-1 times or 3 Times
  1582. //XM_XLAT <dec> // process a pixel
  1583. mov al,[edi] //; pixel = [adr]
  1584. xlat //; pixel = parm[pixel]
  1585. mov [edi],al //; [adr] = pixel
  1586. dec edi //; adr += xstep
  1587. add edx,ebp //; accum += slope
  1588. jnc Fd1 //; if accum overflowed,
  1589. add edi,esi //; adr += ystep
  1590. Fd1:
  1591. dec ecx //; count--
  1592. jz XmNdxXlatDone
  1593. //XM_XLAT <dec> // process a pixel
  1594. mov al,[edi] //; pixel = [adr]
  1595. xlat //; pixel = parm[pixel]
  1596. mov [edi],al //; [adr] = pixel
  1597. dec edi //; adr += xstep
  1598. add edx,ebp //; accum += slope
  1599. jnc Fd2 //; if accum overflowed,
  1600. add edi,esi //; adr += ystep
  1601. Fd2:
  1602. dec ecx //; count--
  1603. jz XmNdxXlatDone
  1604. //XM_XLAT <dec> // process a pixel
  1605. mov al,[edi] //; pixel = [adr]
  1606. xlat //; pixel = parm[pixel]
  1607. mov [edi],al //; [adr] = pixel
  1608. dec edi //; adr += xstep
  1609. add edx,ebp //; accum += slope
  1610. jnc Fd3 //; if accum overflowed,
  1611. add edi,esi //; adr += ystep
  1612. Fd3:
  1613. dec ecx //; count--
  1614. jz XmNdxXlatDone
  1615. //XM_XLAT <dec> // process a pixel
  1616. mov al,[edi] //; pixel = [adr]
  1617. xlat //; pixel = parm[pixel]
  1618. mov [edi],al //; [adr] = pixel
  1619. dec edi //; adr += xstep
  1620. add edx,ebp //; accum += slope
  1621. jnc Fd4 //; if accum overflowed,
  1622. add edi,esi //; adr += ystep
  1623. Fd4:
  1624. dec ecx //; count--
  1625. jnz XmNdxXlatLoop // while (count)
  1626. XmNdxXlatDone:
  1627. pop ebp // restore ebp
  1628. jmp ReturnClipFlags // done
  1629. //----------------------------------------------------------------------------
  1630. XmNdxProc:
  1631. mov esi,panep // get pane pointer
  1632. mov edi,x0_ // x (edi) = x0_ in pane coordinates
  1633. sub edi,[esi+4] //.x0
  1634. mov eax,y0_ // y (esi) = y0_ in pane coordinates
  1635. sub eax,[esi+8] //.y0
  1636. mov esi,eax
  1637. mov eax,sgndy // xbump (eax) = (sgndy=-1) ? -1 : +1
  1638. add eax,eax
  1639. inc eax
  1640. XmNdxProcLoop:
  1641. pushad // callback (x, y)
  1642. call parm
  1643. popad
  1644. add edx,ebx // accum += slope
  1645. jnc F4 // if overflow, y--
  1646. dec esi
  1647. F4: add edi,eax // x += xbump
  1648. dec ecx // count--
  1649. jnz XmNdxProcLoop // while (count)
  1650. jmp ReturnClipFlags // done
  1651. //----------------------------------------------------------------------------
  1652. Vertical:
  1653. // reject if line is left or right of pane
  1654. mov eax,x0
  1655. cmp eax,_L
  1656. jl ReturnReject
  1657. cmp eax,_R
  1658. jg ReturnReject
  1659. // reject if line is above plane
  1660. mov eax,y0
  1661. cmp eax,y1
  1662. jg around1a1
  1663. mov eax,y1
  1664. around1a1:
  1665. cmp eax,_T
  1666. jl ReturnReject
  1667. // reject if line is below plane
  1668. mov eax,y0
  1669. cmp eax,y1
  1670. jl around1b1
  1671. mov eax,y1
  1672. around1b1:
  1673. cmp eax,_B
  1674. jg ReturnReject
  1675. // clip y0, clip y1
  1676. mov eax,y0
  1677. cmp eax,_T
  1678. jg around2a1
  1679. mov eax,_T
  1680. around2a1:
  1681. cmp eax,_B
  1682. jg around2b1
  1683. mov eax,_B
  1684. around2b1:
  1685. mov y0_,eax
  1686. mov eax,y1
  1687. cmp eax,_T
  1688. jg around3a1
  1689. mov eax,_T
  1690. around3a1:
  1691. cmp eax,_B
  1692. jg around3b1
  1693. mov eax,_B
  1694. around3b1:
  1695. mov y1_,eax
  1696. mov eax,x0
  1697. mov x0_,eax
  1698. // calculate ystep (esi)
  1699. mov esi,_W
  1700. xor esi,sgndy
  1701. sub esi,sgndy
  1702. // calculate count (ecx) = abs(y1-y0) + 1
  1703. mov eax,y1_
  1704. sub eax,y0_
  1705. cdq
  1706. xor eax,edx
  1707. sub eax,edx
  1708. mov ecx,eax
  1709. inc ecx
  1710. jmp Straight
  1711. //---------------------------------------------------------------------------
  1712. Horizontal:
  1713. // reject if line is above or below pane
  1714. mov eax,y0
  1715. cmp eax,_T
  1716. jl ReturnReject
  1717. cmp eax,_B
  1718. jg ReturnReject
  1719. // reject if line is left of pane
  1720. mov eax,x0
  1721. cmp eax,x1
  1722. jg around1a
  1723. mov eax,x1
  1724. around1a:
  1725. cmp eax,_L
  1726. jl ReturnReject
  1727. // reject if line is right of pane
  1728. mov eax,x0
  1729. cmp eax,x1
  1730. jl around1b
  1731. mov eax,x1
  1732. around1b:
  1733. cmp eax,_R
  1734. jg ReturnReject
  1735. // clip x0, clip x1
  1736. mov eax,x0
  1737. cmp eax,_L
  1738. jg around2a
  1739. mov eax,_L
  1740. around2a:
  1741. cmp eax,_R
  1742. jl around2b
  1743. mov eax,_R
  1744. around2b:
  1745. mov x0_,eax
  1746. mov eax,x1
  1747. cmp eax,_L
  1748. jg around3a
  1749. mov eax,_L
  1750. around3a:
  1751. cmp eax,_R
  1752. jl around3b
  1753. mov eax,_R
  1754. around3b:
  1755. mov x1_,eax
  1756. mov eax,y0
  1757. mov y0_,eax
  1758. // calculate xstep (esi)
  1759. mov esi,sgndx
  1760. inc esi
  1761. or esi,sgndx
  1762. // calculate count (ecx) = abs(x1-x0) + 1
  1763. mov eax,x1_
  1764. sub eax,x0_
  1765. cdq
  1766. xor eax,edx
  1767. sub eax,edx
  1768. mov ecx,eax
  1769. inc ecx
  1770. jmp Straight
  1771. ;----------------------------------------------------------------------------
  1772. Diagonal:
  1773. // calculate xystep (esi)
  1774. mov esi,_W
  1775. xor esi,sgndy
  1776. sub esi,sgndy
  1777. mov eax,sgndx
  1778. inc eax
  1779. or eax,sgndx
  1780. add esi,eax
  1781. // calculate count (ecx) = abs(x1-x0) + 1
  1782. mov eax,x1_
  1783. sub eax,x0_
  1784. cdq
  1785. xor eax,edx
  1786. sub eax,edx
  1787. mov ecx,eax
  1788. inc ecx
  1789. //----------------------------------------------------------------------------
  1790. Straight:
  1791. // calculate adr (edi), address of first pixel = window_buffer + CP_W*y0 + x0
  1792. //GET_WINDOW_ADDRESS x0_, y0_
  1793. mov eax,y0_
  1794. imul _W
  1795. add eax,_A
  1796. add eax,x0_
  1797. mov edi,eax
  1798. // draw the line with a color, a translation table, or a callback function
  1799. cmp mode,1
  1800. je StraightXlat
  1801. jg StraightProc
  1802. //----------------------------------------------------------------------------
  1803. //StraightDraw:
  1804. mov eax,parm // get line color
  1805. StraightLoop:
  1806. //REPEAT LD_COPIES-1 // repeat code copies-1 times or 3 Times
  1807. //ST_DRAW // process a pixel
  1808. mov [edi],al // [adr] = pixel
  1809. add edi,esi // adr += xystep
  1810. dec ecx // count--
  1811. jz StraightDone
  1812. //ST_DRAW // process a pixel
  1813. mov [edi],al // [adr] = pixel
  1814. add edi,esi // adr += xystep
  1815. dec ecx // count--
  1816. jz StraightDone
  1817. //ST_DRAW // process a pixel
  1818. mov [edi],al // [adr] = pixel
  1819. add edi,esi // adr += xystep
  1820. dec ecx // count--
  1821. jz StraightDone
  1822. //ST_DRAW // process a pixel
  1823. mov [edi],al // [adr] = pixel
  1824. add edi,esi // adr += xystep
  1825. dec ecx // count--
  1826. jnz StraightLoop // while (count)
  1827. StraightDone:
  1828. jmp ReturnClipFlags // done
  1829. //----------------------------------------------------------------------------
  1830. StraightXlat:
  1831. mov ebx,parm // get pointer to translation table
  1832. StraightXlatLoop:
  1833. //REPEAT LD_COPIES-1 // repeat code copies-1 times or 3 Times
  1834. //SW_XLAT // process a pixel
  1835. mov al,[edi] //; pixel = [adr]
  1836. xlat //; pixel = parm[pixel]
  1837. mov [edi],al //; [adr] = pixel
  1838. add edi,esi //; adr += xystep
  1839. dec ecx //; count--
  1840. jz StraightXlatDone
  1841. //SW_XLAT // process a pixel
  1842. mov al,[edi] //; pixel = [adr]
  1843. xlat //; pixel = parm[pixel]
  1844. mov [edi],al //; [adr] = pixel
  1845. add edi,esi //; adr += xystep
  1846. dec ecx //; count--
  1847. jz StraightXlatDone
  1848. //SW_XLAT // process a pixel
  1849. mov al,[edi] //; pixel = [adr]
  1850. xlat //; pixel = parm[pixel]
  1851. mov [edi],al //; [adr] = pixel
  1852. add edi,esi //; adr += xystep
  1853. dec ecx //; count--
  1854. jz StraightXlatDone
  1855. //SW_XLAT // process a pixel
  1856. mov al,[edi] //; pixel = [adr]
  1857. xlat //; pixel = parm[pixel]
  1858. mov [edi],al //; [adr] = pixel
  1859. add edi,esi //; adr += xystep
  1860. dec ecx //; count--
  1861. jnz StraightXlatLoop // while (count)
  1862. StraightXlatDone:
  1863. jmp ReturnClipFlags // done
  1864. //---------------------------------------------------------------------------
  1865. StraightProc:
  1866. mov esi,panep // get pane pointer
  1867. mov edi,x0_ // x (edi) = x0_ in pane coordinates
  1868. sub edi,[esi+4] //.x0
  1869. mov eax,y0_ // y (esi) = y0_ in pane coordinates
  1870. sub eax,[esi+8] //.y0
  1871. mov esi,eax
  1872. xor eax,eax // ybump (eax) = sgn (_dy)
  1873. test _dy,-1
  1874. setnz al
  1875. or eax,sgndy
  1876. xor ebx,ebx // xbump (ebx) = sgn (_dx)
  1877. test _dx,-1
  1878. setnz bl
  1879. or ebx,sgndx
  1880. StraightProcLoop:
  1881. pushad // callback (x, y)
  1882. call parm
  1883. popad
  1884. add esi,eax // y += ybump
  1885. add edi,ebx // x += xbump
  1886. dec ecx // count--
  1887. jnz StraightProcLoop // while (count)
  1888. jmp ReturnClipFlags // done
  1889. // return error code:
  1890. //
  1891. // -2: pane was malformed (or completely off its window)
  1892. // -1: window was malformed
  1893. // 0: line was accepted
  1894. // 1: line was clipped
  1895. // 2: line was rejected
  1896. ReturnClipFlags:
  1897. xor eax,eax
  1898. cmp clip_flags,1
  1899. setae al
  1900. jmp exit
  1901. ReturnReject:
  1902. mov eax,2
  1903. jmp exit
  1904. exit:
  1905. mov lineResult,eax
  1906. }
  1907. return lineResult;
  1908. }
  1909. //----------------------------------------------------------------------------
  1910. //
  1911. // int cdecl VFX_pixel_write (PANE *panep, int x, int y, UBYTE color)
  1912. //
  1913. // This function writes a single pixel.
  1914. //
  1915. // The panep parameter specifies the pane containing the pixel to be written.
  1916. // The x and y parameters specify the pixel coordinates.
  1917. // The color parameter specifies the color to write to the pixel.
  1918. //
  1919. // Return values:
  1920. //
  1921. // 0..255:
  1922. // Pixel value prior to write.
  1923. //
  1924. // -1: Bad window.
  1925. // The height or width of the pane's window is less than one.
  1926. //
  1927. // -2: Bad pane.
  1928. // The height or width of the pane is less than one.
  1929. //
  1930. // -3: Off pane.
  1931. // The specified pixel is off the pane.
  1932. //
  1933. //----------------------------------------------------------------------------
  1934. LONG VFX_pixel_write (PANE *panep, LONG x, LONG y, ULONG color)
  1935. {
  1936. long _L; //Leftmost pixel in Window coord.
  1937. long _T; //Top
  1938. long _R; //Right
  1939. long _B; //Bottom
  1940. MemoryPtr _A; //Base address of Clipped Pane
  1941. long _W; //Width of underlying window (bytes)
  1942. long _CX; //Window x coord. = Pane x coord. + CP_CX
  1943. long _CY; //Window y coord. = Pane x coord. + CP_CY
  1944. int result = 0;
  1945. __asm
  1946. {
  1947. cld
  1948. }
  1949. //Clip Pane to Window Routine
  1950. // get panep (esi)
  1951. // windowp (ebx) = panep->win
  1952. //ASSUME esi:PPANE
  1953. //ASSUME ebx:PWIN
  1954. __asm
  1955. {
  1956. mov esi,panep
  1957. mov ebx,[esi] //This is the Window Pointer
  1958. // _W = windowp->wnd_x1 + 1
  1959. // if _W <= 0, return bad window
  1960. mov eax,[ebx+4] //X1 Window Coord
  1961. inc eax
  1962. mov _W,eax
  1963. jle ReturnBadWindow
  1964. // ecx = Ysize = windowp->wnd_y1 + 1
  1965. // if <= 0, return bad window
  1966. mov eax,[ebx+8] //y1 Window Coord
  1967. inc eax
  1968. mov ecx,eax
  1969. jle ReturnBadWindow
  1970. // clip pane to window:
  1971. // pane_x0 = max (pane->x0, 0)
  1972. // pane_y0 = max (pane->y0, 0)
  1973. // pane_x1 = min (pane->x1, _W - 1)
  1974. // pane_y1 = min (pane->x1, (Ysize=ecx) - 1)
  1975. mov eax,[esi+4] //x0 in Pane Coord
  1976. mov _CX,eax
  1977. cmp eax,0
  1978. jg around1
  1979. mov eax,0
  1980. around1:
  1981. mov _L,eax
  1982. mov eax,[esi+8] //y0 in Pane Coord
  1983. mov _CY,eax
  1984. cmp eax,0
  1985. jg around2
  1986. mov eax,0
  1987. around2:
  1988. mov _T,eax
  1989. mov eax,[esi+12] //X1 in Pane Coord
  1990. mov edx,_W
  1991. dec edx
  1992. cmp eax,edx
  1993. jl around3
  1994. mov eax,edx
  1995. around3:
  1996. mov _R,eax
  1997. mov eax,[esi+16] //y1 in Pane Coord
  1998. mov edx,ecx
  1999. dec edx
  2000. cmp eax,edx
  2001. jl around4
  2002. mov eax,edx
  2003. around4:
  2004. mov _B,eax
  2005. // exit if pane is malformed or completely off window:
  2006. // if _B < &vname&_T, return bad pane
  2007. // if _R < &vname&_L, return bad pane
  2008. mov eax,_R
  2009. cmp eax,_L
  2010. jl ReturnBadPane
  2011. mov eax,_B
  2012. cmp eax,_T
  2013. jl ReturnBadPane
  2014. mov eax,[ebx] //Buffer in Window
  2015. mov _A,eax
  2016. jmp exit1
  2017. ReturnBadWindow:
  2018. mov eax,-1
  2019. jmp exit1
  2020. }
  2021. __asm
  2022. {
  2023. ReturnBadPane:
  2024. mov eax,-2
  2025. }
  2026. exit1:
  2027. __asm
  2028. {
  2029. // transform x & y to window coord's
  2030. mov ecx,x
  2031. mov ebx,y
  2032. //CONVERT_REG_PAIR_PANE_TO_WINDOW ecx, ebx
  2033. add ecx,_CX
  2034. add ebx,_CY
  2035. // clip pixel to pane
  2036. cmp ecx,_L
  2037. jl ReturnOffPane
  2038. cmp ecx,_R
  2039. jg ReturnOffPane
  2040. cmp ebx,_T
  2041. jl ReturnOffPane
  2042. cmp ebx,_B
  2043. jg ReturnOffPane
  2044. // adr (ebx) = window->buffer + CP_W * y + x
  2045. //GET_WINDOW_ADDRESS x0_, y0_
  2046. mov eax,ebx
  2047. imul _W
  2048. add eax,_A
  2049. add eax,ecx
  2050. mov edi,eax
  2051. mov ebx,eax
  2052. // write the pixel
  2053. mov dl,BYTE PTR color
  2054. mov [ebx],dl
  2055. // return prior_value
  2056. ret
  2057. // error returns
  2058. ReturnOffPane:
  2059. mov eax,-3
  2060. ret
  2061. }
  2062. return(result);
  2063. }
  2064. //----------------------------------------------------------------------------
  2065. //
  2066. // int cdecl VFX_pixel_read (PANE *panep, int x, int y)
  2067. //
  2068. // This function reads a single pixel.
  2069. //
  2070. // The panep parameter specifies the pane containing the pixel to be written.
  2071. // The x and y parameters specify the pixel coordinates.
  2072. //
  2073. // Return values:
  2074. //
  2075. // 0..255:
  2076. // Pixel value.
  2077. //
  2078. // -1: Bad window.
  2079. // The height or width of the pane's window is less than one.
  2080. //
  2081. // -2: Bad pane.
  2082. // The height or width of the pane is less than one.
  2083. //
  2084. // -3: Off pane.
  2085. // The specified pixel is off the pane.
  2086. //
  2087. //---------------------------------------------------------------------------
  2088. LONG VFX_pixel_read (PANE *panep, LONG x, LONG y)
  2089. {
  2090. long _L; //Leftmost pixel in Window coord.
  2091. long _T; //Top
  2092. long _R; //Right
  2093. long _B; //Bottom
  2094. MemoryPtr _A; //Base address of Clipped Pane
  2095. long _W; //Width of underlying window (bytes)
  2096. long _CX; //Window x coord. = Pane x coord. + CP_CX
  2097. long _CY; //Window y coord. = Pane x coord. + CP_CY
  2098. int result = 0;
  2099. __asm
  2100. {
  2101. cld
  2102. }
  2103. //Clip Pane to Window Routine
  2104. // get panep (esi)
  2105. // windowp (ebx) = panep->win
  2106. //ASSUME esi:PPANE
  2107. //ASSUME ebx:PWIN
  2108. __asm
  2109. {
  2110. mov esi,panep
  2111. mov ebx,[esi] //This is the Window Pointer
  2112. // _W = windowp->wnd_x1 + 1
  2113. // if _W <= 0, return bad window
  2114. mov eax,[ebx+4] //X1 Window Coord
  2115. inc eax
  2116. mov _W,eax
  2117. jle ReturnBadWindow
  2118. // ecx = Ysize = windowp->wnd_y1 + 1
  2119. // if <= 0, return bad window
  2120. mov eax,[ebx+8] //y1 Window Coord
  2121. inc eax
  2122. mov ecx,eax
  2123. jle ReturnBadWindow
  2124. // clip pane to window:
  2125. // pane_x0 = max (pane->x0, 0)
  2126. // pane_y0 = max (pane->y0, 0)
  2127. // pane_x1 = min (pane->x1, _W - 1)
  2128. // pane_y1 = min (pane->x1, (Ysize=ecx) - 1)
  2129. mov eax,[esi+4] //x0 in Pane Coord
  2130. mov _CX,eax
  2131. cmp eax,0
  2132. jg around1
  2133. mov eax,0
  2134. around1:
  2135. mov _L,eax
  2136. mov eax,[esi+8] //y0 in Pane Coord
  2137. mov _CY,eax
  2138. cmp eax,0
  2139. jg around2
  2140. mov eax,0
  2141. around2:
  2142. mov _T,eax
  2143. mov eax,[esi+12] //X1 in Pane Coord
  2144. mov edx,_W
  2145. dec edx
  2146. cmp eax,edx
  2147. jl around3
  2148. mov eax,edx
  2149. around3:
  2150. mov _R,eax
  2151. mov eax,[esi+16] //y1 in Pane Coord
  2152. mov edx,ecx
  2153. dec edx
  2154. cmp eax,edx
  2155. jl around4
  2156. mov eax,edx
  2157. around4:
  2158. mov _B,eax
  2159. // exit if pane is malformed or completely off window:
  2160. // if _B < &vname&_T, return bad pane
  2161. // if _R < &vname&_L, return bad pane
  2162. mov eax,_R
  2163. cmp eax,_L
  2164. jl ReturnBadPane
  2165. mov eax,_B
  2166. cmp eax,_T
  2167. jl ReturnBadPane
  2168. mov eax,[ebx] //Buffer in Window
  2169. mov _A,eax
  2170. jmp exit1
  2171. ReturnBadWindow:
  2172. mov eax,-1
  2173. jmp exit1
  2174. }
  2175. __asm
  2176. {
  2177. ReturnBadPane:
  2178. mov eax,-2
  2179. }
  2180. exit1:
  2181. __asm
  2182. {
  2183. // transform x & y to window coord's
  2184. mov ecx,x
  2185. mov ebx,y
  2186. //CONVERT_REG_PAIR_PANE_TO_WINDOW ecx, ebx
  2187. add ecx,_CX
  2188. add ebx,_CY
  2189. // clip pixel to pane
  2190. cmp ecx,_L
  2191. jl ReturnOffPane
  2192. cmp ecx,_R
  2193. jg ReturnOffPane
  2194. cmp ebx,_T
  2195. jl ReturnOffPane
  2196. cmp ebx,_B
  2197. jg ReturnOffPane
  2198. // adr (ebx) = window->buffer + CP_W * y + x
  2199. //GET_WINDOW_ADDRESS x0_, y0_
  2200. mov eax,ebx
  2201. imul _W
  2202. add eax,_A
  2203. add eax,ecx
  2204. mov edi,eax
  2205. mov ebx,eax
  2206. // read and return the pixel
  2207. xor eax,eax
  2208. mov al,[ebx]
  2209. ret
  2210. // error returns
  2211. ReturnOffPane:
  2212. mov eax,-3
  2213. mov result, eax
  2214. ret
  2215. }
  2216. return(result);
  2217. }