12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008 |
- //-----------------------------------------------------------
- //
- // FASA Interactive Technologies
- //
- // VFX Tile Draw Routine
- //
- // Started April 30, 1996
- // FFS
- //
- //-----------------------------------------------------------
- //-----------------------------------------------------------
- // Include Files
- #ifndef DSTD_H
- #include "dstd.h"
- #endif
- #ifndef VFX_H
- #include "vfx.h"
- #endif
- static unsigned long pwXMax,count; // Must be static for assembly optimizations
- static unsigned char *FadeTable; // Must be static for assembly optimizations
- //-----------------------------------------------------------
- struct tileStruct
- {
- byte tileHotSpotX;
- byte tileHotSpotY;
- byte numScanLines;
- byte numScanColumns;
- };
- //-----------------------------------------------------------
- struct newShapeStruct
- {
- long header;
- short tileHotSpotX;
- short tileHotSpotY;
- short numScanLines;
- short numScanColumns;
- };
- #define FULLY_CLIPPED 0xCDCF0001
- #define FORMAT_SPEC 0xFEEDABBA
- #define BLACK 0x10101010
- //-----------------------------------------------------------
- // This one is called if the cameraScale is 100. No drop
- // of any pixels. Straight BLT to screen.
- long VFX_nTile_draw (PANE* pane, void *tile, LONG hotX, LONG hotY, MemoryPtr fadeTable)
- {
- //-----------------------------------------
- // Format of tile shape data is NEW!!
- // Byte -- Hot Spot X.
- // Byte -- Hot Spot Y.
- // Byte -- NumScanLines. (height)
- // Byte -- NumScanColumns. (width)
- // Word -- One word for each scanline indicating offset into main data for that scanline.
- // Bytes -- Main Shape data. Each scanline pointed to by above table.
- // The main difference between .fsx and .gsx files are in the main data.
- // Because there is no end scanline marker, the length of each Blt can be
- // determined and a MUCH faster rep movsd can be used to Blt the data.
- //------------------------------------------------------
- //-------------------------------------------------------
- // Create Important Data from tile data.
- MemoryPtr tileData = (MemoryPtr)tile + sizeof(tileStruct);
- tileStruct *tileInfo = (tileStruct *)tile;
-
- unsigned long *yOffsetTable = (unsigned long *)(tileData);
- pwXMax = pane->window->x_max+1;
- long paneX0 = (pane->x0 < 0) ? 0 : pane->x0;
- long paneY0 = (pane->y0 < 0) ? 0 : pane->y0;
- long paneX1 = (pane->x1 >= (long)pwXMax) ? pane->window->x_max : pane->x1;
- long paneY1 = (pane->y1 >= (pane->window->y_max+1)) ? pane->window->y_max : pane->y1;
- long scanLines = tileInfo->numScanLines;
- long scanCol = tileInfo->numScanColumns;
- long topLeftX = (hotX + paneX0) - tileInfo->tileHotSpotX;
- long topLeftY = (hotY + paneY0) - tileInfo->tileHotSpotY; //In theory, tileHotSpotY is always zero!
-
- if ( (topLeftX >= paneX1) ||
- (topLeftY >= paneY1) ||
- (topLeftX <= (paneX0 - scanCol)) ||
- (topLeftY <= (paneY0 - scanLines)))
- return(FULLY_CLIPPED);
- MemoryPtr screenBuffer = pane->window->buffer + ((topLeftY > paneY0) ? topLeftY*pwXMax : paneY0*pwXMax);
- long firstScanOffset = (topLeftY < paneY0) ? paneY0 - topLeftY : 0;
-
- long lastScanOffset = ((topLeftY + scanLines) > paneY1) ? paneY1 - topLeftY + 1 : scanLines;
- yOffsetTable += firstScanOffset;
- if( (topLeftX>paneX0) && ((topLeftX+scanCol) < paneX1) )
- {
- FadeTable=fadeTable;
- screenBuffer+=topLeftX;
- count=lastScanOffset-firstScanOffset;
- //
- // No clipping, whole tile is on screen
- //
- _asm{
- push ebp
- mov edx,screenBuffer
- mov esi,tile
- mov ebp,yOffsetTable
- mov eax,FadeTable
- add esi,[ebp]
- cmp eax,-1
- jz DoBlack
- test eax,eax
- jnz DoFade
- //
- // Normal
- //
- DisplayTile:
- xor ebx,ebx
- mov eax,[ebp+4]
- mov ecx,[ebp]
- lea ebp,[ebp+4]
- sub eax,ecx
- mov bl,[esi]
- mov ecx,0
- jz DisplayTile1
- lea edi,[ebx+edx]
- dec eax
- sub ecx,edi
- inc esi
- and ecx,3
- sub eax,ecx
- jle DisplayTile2
- rep movsb
- mov ecx,eax
- and eax,3 ; Main loop, copying an unclipped tile
- shr ecx,2
- jz DisplayTile2
- DisplayTile3:
- mov ebx,[esi]
- add esi,4
- mov [edi],ebx
- add edi,4
- dec ecx
- jnz DisplayTile3
- DisplayTile2:
- add eax,ecx
- jz DisplayTile1
- DisplayTile4:
- mov bl,[esi]
- inc esi
- mov [edi],bl
- inc edi
- dec eax
- jnz DisplayTile4
- DisplayTile1:
- mov ebx,pwXMax
- mov eax,count
- add edx,ebx
- dec eax
- mov count,eax
- jnz DisplayTile
- jmp done
- //
- // Black
- //
- DoBlack: xor ebx,ebx
- mov eax,[ebp+4]
- mov ecx,[ebp]
- lea ebp,[ebp+4]
- sub eax,ecx
- mov bl,[esi]
- mov ecx,0
- jz DoBlack1
- lea edi,[ebx+edx]
- dec eax
- sub ecx,edi
- lea esi,[esi+eax+1]
- and ecx,3
- mov ebx,eax
- mov eax,BLACK
- sub ebx,ecx
- jle DoBlack2
- rep stosb
- mov ecx,ebx
- and ebx,3 ; Main loop, blacking out an unclipped tile
- shr ecx,2
- rep stosd
- DoBlack2: add ecx,ebx
- rep stosb
- DoBlack1: mov ebx,pwXMax
- mov eax,count
- add edx,ebx
- dec eax
- mov count,eax
- jnz DoBlack
- jmp done
- //
- // Fade
- //
- DoFade: xor ebx,ebx
- mov ecx,[ebp+4]
- mov eax,[ebp]
- lea ebp,[ebp+4]
- sub ecx,eax
- mov bl,[esi]
- lea ecx,[ecx-1]
- jz DoFade1
- lea edi,[ebx+edx]
- inc esi
- // Fade inner loop
- push edx
- mov edx,FadeTable
- mov bl,[esi]
- inc esi
- DoFade0: inc edi
- dec ecx
- mov al,[edx+ebx]
- mov bl,[esi]
- mov [edi-1],al
- lea esi,[esi+1]
-
- jnz DoFade0
- pop edx
- dec esi
- DoFade1: mov ebx,pwXMax
- mov eax,count
- add edx,ebx
- dec eax
- mov count,eax
- jnz Dofade
- done:
- pop ebp
- }
- }
- else
- //
- // This tile needs to be clipped
- //
- {
- unsigned long currentOffset = *yOffsetTable++;
- unsigned long nextOffset=*yOffsetTable++;
- for (long scanLine = firstScanOffset; scanLine<lastScanOffset; scanLine++)
- {
- __asm
- {
- mov esi, tile
- xor ebx, ebx
- add esi, currentOffset
- xor eax, eax
- mov al, BYTE PTR [esi]
- inc esi
- add eax, topLeftX
- mov edi, screenBuffer
- add edi, eax
- mov ecx, nextOffset
- sub ecx, currentOffset
- xor edx, edx
- dec ecx
- mov edx, eax
- add edx, ecx
- cmp eax, paneX0
- jge SHORT LINE207
-
- mov ebx, paneX0
- sub ebx, eax
-
- add esi, ebx
- add edi, ebx
- LINE207:
- cmp edx, paneX1
- jle SHORT LINE214
-
- sub edx, paneX1
- dec edx
- jmp SHORT LEAVE_EDX
-
- LINE214:
- xor edx, edx
- LEAVE_EDX:
- sub ecx, ebx
- sub ecx, edx
-
- cmp ecx, 0
- jle SHORT NO_DRAW
-
- mov eax,fadeTable
- cmp eax,-1
- jz SHORT BLT_BLACK
-
- test eax,eax
- jz BLT_FAST
-
- //FADE_BLT_TOP:
- xor edx, edx
- mov ebx,fadeTable
- mov dl, [esi]
- inc esi
- Blt_fade1:
- inc edi
- dec ecx
- mov al, [edx+ebx]
- mov dl, [esi]
- mov BYTE PTR [edi-1], al
- lea esi,[esi+1]
-
- jnz Blt_fade1
- jmp short NO_DRAW
- BLT_BLACK:
- mov ebx,ecx ; DWORD align edi when possible
- sub ecx,edi
- mov eax,BLACK
- sub ecx,ebx
- and ecx,3
- sub ebx,ecx
- jle blt_black1
- rep stosb
- mov ecx,ebx
- and ebx,3
- shr ecx,2
- rep stosd
- blt_black1: add ecx,ebx
- rep stosb
- jmp SHORT NO_DRAW
- BLT_FAST:
- mov eax,ecx ; DWORD align edi when possible
- sub ecx,edi
- sub ecx,eax
- and ecx,3
- sub eax,ecx
- jle blt_fast1
- rep movsb
- mov ecx,eax
- and eax,3
- shr ecx,2
- rep movsd
- blt_fast1: add ecx,eax
- rep movsb
- NO_DRAW:
- }
- screenBuffer += pwXMax;
- currentOffset = nextOffset;
- nextOffset = *yOffsetTable++;
- }
- }
- //-----------------------------------------------------------
-
- return(0x00);
- }
- //----------------------------------------------------------------------------
- //
- // long VFX_shape_origin(void *shape_table, LONG shape_number);
- //
- // Returns hotspot of the shape (in pixels) relative to the upper left bounds).
- // (E)AX=x E(AX)=y.
- //
- //----------------------------------------------------------------------------
- long VFX_shape_origin(void *shape_table, LONG shape_number)
- {
- long result = -1;
- __asm
- {
- mov esi,shape_table
- add esi,8 //skip to offsets
-
- mov eax,shape_number //point to shape offset ptr
- shl eax,3 //mul eax by sizeof 2 longs
- add esi,eax
- mov esi,[esi] //get shape offset ptr
- add esi,shape_table //add base address
- mov eax,[esi+4] //SHAPEHEADER.origin
- mov result,eax
- }
- return result;
- }
- //----------------------------------------------------------------------------
- //
- // long VFX_shape_resolution(void *shape_table, LONG shape_number);
- //
- // Returns x,y resolution (image size) in pixels. (E)AX=x E(AX)=y.
- //
- //----------------------------------------------------------------------------
- long VFX_shape_resolution(void *shape_table, LONG shape_number)
- {
- long result = 0;
- __asm
- {
- mov esi,shape_table
- add esi,8 //skip to offsets
-
- mov eax,shape_number //point to shape offset ptr
- shl eax,3 //mul eax by sizeof 2 longs
- add esi,eax
- mov esi,[esi] //get shape offset ptr
- add esi,shape_table //add base address
- mov eax,[esi+16] //SHAPEHEADER.xmax ;eax = xmax - xmin
- sub eax,[esi+8] //SHAPEHEADER.xmin
- inc eax // + 1
- mov ebx,[esi+20] //SHAPEHEADER.ymax ;ebx = ymax - ymin
- sub ebx,[esi+12] //SHAPEHEADER.ymin
- inc ebx // + 1
- shl eax,16
- and eax,0xffff0000
- add eax,ebx
- mov result,eax
- }
- return result;
- }
- //----------------------------------------------------------------------------
- //
- // long VFX_shape_minxy(void *shape_table, LONG shape_number);
- //
- // Returns min x,min y in pixels. (E)AX=x E(AX)=y.
- //
- //---------------------------------------------------------------------------
- long VFX_shape_minxy(void *shape_table, LONG shape_number)
- {
- long result = 0;
- __asm
- {
- mov esi,shape_table
- add esi,8 //skip to offsets
-
- mov eax,shape_number //point to shape offset ptr
- shl eax,3 //mul eax by sizeof 2 longs
- add esi,eax
- mov esi,[esi] //get shape offset ptr
- add esi,shape_table //add base address
- mov eax,[esi+8] //SHAPEHEADER.xmin
- shl eax,16
- mov ebx,[esi+12] //SHAPEHEADER.ymin
- and eax,0xffff0000
- add eax,ebx
- mov result, eax
- }
- return result;
- }
- //;----------------------------------------------------------------------------
- //;
- //; long VFX_shape_bounds(void *shape_table, LONG shape_number);
- //;
- //; Returns width,height of the shape (including transparent areas) in pixels. (E)AX=x E(AX)=y.
- //; (E)AX=x E(AX)=y.
- //;
- //;----------------------------------------------------------------------------
- long VFX_shape_bounds (void *shape_table, long shape_number)
- {
- long boundsResult = -1;
- __asm
- {
- mov esi,shape_table
- add esi,8 //skip to offsets
-
- mov eax,shape_number //point to shape offset ptr
- shl eax,3 //mul eax by sizeof 2 longs
- add esi,eax
- mov esi,[esi] //get shape offset ptr
- add esi,shape_table //add base address
- mov eax,[esi] //Bounds is First Member of struct
- mov boundsResult, eax
- }
- return boundsResult;
- }
- //;----------------------------------------------------------------------------
- //;
- //; long VFX_shape_count(void *shape_table);
- //;
- //; Returns number of shapes references in the specified shape table. Each
- //; shape may have one or more references.
- //;
- //;----------------------------------------------------------------------------
- long VFX_shape_count (void *shape_table)
- {
- long countResult = 0;
- __asm
- {
- mov esi,shape_table
- mov eax,[esi+4]
- mov countResult,eax
- }
- return countResult;
- }
- //;----------------------------------------------------------------------------
- //;
- //; int cdecl VFX_line_draw (PANE *panep, int x0, int y0, int x1, int y1,
- //; int mode, int parm);
- //;
- //; This function clips and draws a line to a pane.
- //;
- //; The panep parameter specifies the pane.
- //;
- //; The x0 and y0 parameters specify the initial endpoint of the line.
- //; The x1 and y1 parameters specify the final endpoint of the line.
- //;
- //; The mode parameter specifies the operation to perform on each point
- //; in the line.
- //;
- //; If mode is... parm specifies...
- //;
- //; DRAW a color
- //; TRANSLATE the address of a color translation table
- //; EXECUTE the address of a caller-provided function
- //;
- //; If mode is DRAW (0), the line is drawn in a solid color specified by
- //; parm.
- //;
- //; If mode is TRANSLATE (1), the line is drawn with color translation.
- //; Each pixel along the path of the line is replaced with the correspond-
- //; ing entry in the color translation table specified by parm.
- //;
- //; If mode is EXECUTE (2), the line is drawn with the aid of a callback
- //; function specifed by parm. For each point on the line, VFX_line_draw()
- //; executes the callback function, passing it the coordinates of the point.
- //;
- //; The callback function must use cdecl parameter passing, and its para-
- //; meter list must be (int x, int y). The function's return type is not
- //; important; VFX_line_draw() ignores the return value (if any).
- //;
- //; VFX_line_draw() clips the line to the pane. The locus of the clipped
- //; line is the same for all modes and is guaranteed to be identical to the
- //; intersection of the loci of the unclipped line and the pane. Moreover,
- //; plotting always proceeds from (x0,y0) to (x1,y1) regardless of the
- //; relative orientation of the two points.
- //;
- //; The locus of the clipped line consists of all points in the pane whose
- //; minor-axis distance* from the ideal line is less than or equal to 1/2,
- //; with the following exception. In places where the ideal line passes
- //; exactly halfway between two pixels which share the same major-axis co-
- //; ordinate, only one of the two points is plotted. The selection method
- //; is unspecified, but is consistent throughout the line.
- //;
- //; * The minor-axis distance from a point P to a line L is the absolute
- //; difference between the minor-axis coordinates of P and Q where Q is
- //; the point on L having the same major-axis coordinate as P. (Here,
- //; major-axis and minor axis are determined by L. The major axis is
- //; the axis in which the endpoints of L differ the most. Likewise the
- //; minor-axis is the one in which the endpoints differ the least).
- //;
- //; VFX_line_draw is reentrant, so callback functions can use it.
- //;
- //;
- //; Examples:
- //;
- //; #define HELIOTROPE 147
- //; UBYTE color_negative[256];
- //; void cdecl DrawDiamond (int x, int y);
- //;
- //; VFX_line_draw (pane, Px, Py, Qx, Qy, DRAW, HELIOTROPE);
- //; draws a line from (Px,Py) to (Qx,Qy) using the color HELIOTROPE.
- //;
- //; VFX_line_draw (pane, Px, Py, Qx, Qy, TRANSLATE, (int) color_negative);
- //; draws a line from (Px,Py) to (Qx,Qy) replacing each pixel with its
- //; color negative (as specified by the table color_negative).
- //;
- //; VFX_line_draw (pane, Px, Py, Qx, Qy, EXECUTE, (int) DrawDiamond);
- //; draws a line of diamonds from (Px,Py) to (Qx,Qy) using the
- //; caller-provided function DrawDiamond().
- //;
- //; Return values:
- //;
- //; -2: pane was malformed or completely outside its window
- //; -1: window was malformed
- //; 0: all of the line was inside the pane and was drawn without clipping
- //; 1: some of the line was inside the pane and was drawn after clipping
- //; 2: the line was completely outside the pane and was not drawn
- //;
- //;----------------------------------------------------------------------------
- LONG VFX_line_draw (PANE *panep, LONG x0, LONG y0,
- LONG x1, LONG y1, LONG mode, LONG parm)
- {
- long _dx, absdx, sgndx;
- long _dy, absdy, sgndy;
- long sgndxdy, slope;
- long x0_, y0_, x1_, y1_;
- long clip_flags;
-
- long _L; //Leftmost pixel in Window coord.
- long _T; //Top
- long _R; //Right
- long _B; //Bottom
-
- MemoryPtr _A; //Base address of Clipped Pane
- long _W; //Width of underlying window (bytes)
-
- long _CX; //Window x coord. = Pane x coord. + CP_CX
- long _CY; //Window y coord. = Pane x coord. + CP_CY
- long lineResult;
- __asm
- {
- cld
- }
- //Clip Pane to Window Routine
- // get panep (esi)
- // windowp (ebx) = panep->win
- //ASSUME esi:PPANE
- //ASSUME ebx:PWIN
- __asm
- {
- mov esi,panep
- mov ebx,[esi] //This is the Window Pointer
- // _W = windowp->wnd_x1 + 1
- // if _W <= 0, return bad window
-
- mov eax,[ebx+4] //X1 Window Coord
- inc eax
- mov _W,eax
- jle ReturnBadWindow
-
- // ecx = Ysize = windowp->wnd_y1 + 1
- // if <= 0, return bad window
- mov eax,[ebx+8] //y1 Window Coord
- inc eax
- mov ecx,eax
- jle ReturnBadWindow
- // clip pane to window:
- // pane_x0 = max (pane->x0, 0)
- // pane_y0 = max (pane->y0, 0)
- // pane_x1 = min (pane->x1, _W - 1)
- // pane_y1 = min (pane->x1, (Ysize=ecx) - 1)
- mov eax,[esi+4] //x0 in Pane Coord
- mov _CX,eax
- cmp eax,0
- jg around1
- mov eax,0
- around1:
- mov _L,eax
-
- mov eax,[esi+8] //y0 in Pane Coord
- mov _CY,eax
- cmp eax,0
- jg around2
- mov eax,0
- around2:
- mov _T,eax
-
- mov eax,[esi+12] //X1 in Pane Coord
- mov edx,_W
- dec edx
- cmp eax,edx
- jl around3
- mov eax,edx
- around3:
- mov _R,eax
-
- mov eax,[esi+16] //y1 in Pane Coord
- mov edx,ecx
- dec edx
- cmp eax,edx
- jl around4
- mov eax,edx
- around4:
- mov _B,eax
- // exit if pane is malformed or completely off window:
- // if _B < &vname&_T, return bad pane
- // if _R < &vname&_L, return bad pane
- mov eax,_R
- cmp eax,_L
- jl ReturnBadPane
-
- mov eax,_B
- cmp eax,_T
- jl ReturnBadPane
- mov eax,[ebx] //Buffer in Window
- mov _A,eax
- jmp exit1
- ReturnBadWindow:
- mov eax,-1
- jmp exit1
- }
- __asm
- {
- ReturnBadPane:
- mov eax,-2
- }
- exit1:
- __asm
- {
- //Convert Quad Pane to Window
- mov eax,_CX
- add x0,eax
- add x1,eax
- mov eax,_CY
- add y0,eax
- add y1,eax
- // calculate dx, absdx, and sgndx
-
- mov eax,x1
- sub eax,x0
- mov _dx,eax
-
- cdq
- mov sgndx,edx
-
- xor eax,edx
- sub eax,edx
- mov absdx,eax
- // calculate dy, absdy, and sgndy
-
- mov eax,y1
- sub eax,y0
- mov _dy,eax
-
- cdq
- mov sgndy,edx
-
- xor eax,edx
- sub eax,edx
- mov absdy,eax
- // make working copies of endpoint coordinates
- mov eax,x0
- mov x0_,eax
- mov eax,x1
- mov x1_,eax
- mov eax,y0
- mov y0_,eax
- mov eax,y1
- mov y1_,eax
- // handle special cases -- vertical, horizontal
-
- cmp _dx,0
- je Vertical
-
- cmp _dy,0
- je Horizontal
-
- // calculate sgndxdy
-
- mov eax,sgndx
- xor eax,sgndy
- mov sgndxdy,eax
- // calculate slope
-
- mov edx,absdx
- mov ebx,absdy
- mov eax,0xFFFFFFFF
-
- cmp edx,ebx
- je slope2
- jl slope1
-
- xchg edx,ebx
- slope1:
- xor eax,eax
- div ebx
- slope2:
- mov slope,eax
- // clip line to pane
- mov clip_flags,0
- clip_loop:
- xor edx,edx
- // calculate clip0 (dl)
-
- mov eax,x0_
- sub eax,_L
- shl eax,1
- adc dl,dl
-
- mov eax,_R
- sub eax,x0_
- shl eax,1
- adc dl,dl
-
- mov eax,y0_
- sub eax,_T
- shl eax,1
- adc dl,dl
-
- mov eax,_B
- sub eax,y0_
- shl eax,1
- adc dl,dl
- // calculate clip1 (dh)
- mov eax,x1_
- sub eax,_L
- shl eax,1
- adc dh,dh
-
- mov eax,_R
- sub eax,x1_
- shl eax,1
- adc dh,dh
-
- mov eax,y1_
- sub eax,_T
- shl eax,1
- adc dh,dh
-
- mov eax,_B
- sub eax,y1_
- shl eax,1
- adc dh,dh
- // remember clip flags for final return value
- or clip_flags,edx
- // accept if line is completely in the pane
- or edx,edx
- jz Accept
- // reject if line is completely above, below, left of, or right of the pane
- test dl,dh
- jnz ReturnReject
- // dispatch to appropriate clipper
-
- mov ebx,absdx
- cmp ebx,absdy
- jl ClipYmajor
- //ClipXmajor:
- // clip (x0,y0)
- test dl,1000B
- jnz Xmaj_x0_lo
- test dl,0100B
- jnz Xmaj_x0_hi
- test dl,0010B
- jnz Xmaj_y0_lo
- test dl,0001B
- jnz Xmaj_y0_hi
- // clip (x1,y1)
- test dh,1000B
- jnz Xmaj_x1_lo
- test dh,0100B
- jnz Xmaj_x1_hi
- test dh,0010B
- jnz Xmaj_y1_lo
- test dh,0001B
- jnz Xmaj_y1_hi
-
- jmp clip_loop
- ClipYmajor:
- // clip (x0,y0)
- test dl,1000B
- jnz Ymaj_x0_lo
- test dl,0100B
- jnz Ymaj_x0_hi
- test dl,0010B
- jnz Ymaj_y0_lo
- test dl,0001B
- jnz Ymaj_y0_hi
- // clip (x1,y1)
- test dh,1000B
- jnz Ymaj_x1_lo
- test dh,0100B
- jnz Ymaj_x1_hi
- test dh,0010B
- jnz Ymaj_y1_lo
- test dh,0001B
- jnz Ymaj_y1_hi
-
- jmp clip_loop
- Xmaj_x0_lo:
- // x0_ = CP_L;
- // y0_ = y0 + sgndxdy * floor ((x0_-x0)*slope)+1/2);
-
- mov eax,_L
- mov x0_,eax
- sub eax,x0
-
- mul slope
- add eax,0x80000000
- adc edx,0
- mov eax,edx
-
- mov edx,sgndxdy
-
- xor eax,edx
- sub eax,edx
-
- add eax,y0
- mov y0_,eax
-
- jmp clip_loop
- Ymaj_x0_lo:
- // x0_ = CP_L;
- // y0_ = y0 + sgndxdy * ceil ((x0_-x0-1/2)/slope);
-
- mov eax, _L
- mov x0_, eax
- sub eax,x0
-
- mov edx,eax
- dec edx
- mov eax,0x80000000
- div slope
-
- cmp edx,1
- sbb eax,-1
-
- mov edx,sgndxdy
-
- xor eax,edx
- sub eax,edx
-
- add eax,y0
- mov y0_,eax
-
- jmp clip_loop
-
- Xmaj_x0_hi:
- // x0_ = CP_R;
- // y0_ = y0 - sgndxdy * floor ((x0-CP_R)*slope)+1/2);
- mov eax,_R
- mov x0_,eax
- sub eax,x0
- neg eax
-
- mul slope
- add eax,0x80000000
- adc edx,0
- mov eax,edx
-
- mov edx,sgndxdy
- not edx
-
- xor eax,edx
- sub eax,edx
-
- add eax,y0
- mov y0_,eax
-
- jmp clip_loop
-
- Ymaj_x0_hi:
- // x0_ = CP_R;
- // y0_ = y0 - sgndxdy * ceil ((x0-x0_-1/2)/slope);
- mov eax,_R
- mov x0_,eax
- sub eax,x0
- neg eax
-
- mov edx,eax
- dec edx
- mov eax,0x80000000
- div slope
-
- cmp edx,1
- sbb eax,-1
-
- mov edx,sgndxdy
- not edx
-
- xor eax,edx
- sub eax,edx
-
- add eax,y0
- mov y0_,eax
-
- jmp clip_loop
- Ymaj_y0_lo:
- // y0_ = CP_T;
- // x0_ = x0 + sgndxdy * floor ((y0_-y0)*slope)+1/2);
- mov eax,_T
- mov y0_,eax
- sub eax,y0
-
- mul slope
- add eax,0x80000000
- adc edx,0
- mov eax,edx
-
- mov edx,sgndxdy
-
- xor eax,edx
- sub eax,edx
-
- add eax,x0
- mov x0_,eax
-
- jmp clip_loop
-
- Xmaj_y0_lo:
- // y0_ = CP_T;
- // x0_ = x0 + sgndxdy * ceil ((y0_-y0-1/2)/slope);
-
- mov eax,_T
- mov y0_,eax
- sub eax,y0
-
- mov edx,eax
- dec edx
- mov eax,0x80000000
- div slope
-
- cmp edx,1
- sbb eax,-1
-
- mov edx,sgndxdy
-
- xor eax,edx
- sub eax,edx
-
- add eax,x0
- mov x0_,eax
-
- jmp clip_loop
- Ymaj_y0_hi:
- // y0_ = CP_B;
- // x0_ = x0 - sgndxdy * floor ((y0-y0_)*slope+1/2);
- mov eax,_B
- mov y0_,eax
- sub eax,y0
- neg eax
-
- mul slope
- add eax,0x80000000
- adc edx,0
- mov eax,edx
-
- mov edx,sgndxdy
- not edx
-
- xor eax,edx
- sub eax,edx
-
- add eax,x0
- mov x0_,eax
-
- jmp clip_loop
- Xmaj_y0_hi:
- // y0_ = CP_B;
- // x0_ = x0 - sgndxdy * ceil ((y0-y0_-1/2)/slope);
-
- mov eax,_B
- mov y0_,eax
- sub eax,y0
- neg eax
-
- mov edx,eax
- dec edx
- mov eax,0x80000000
- div slope
-
- cmp edx,1
- sbb eax,-1
-
- mov edx,sgndxdy
- not edx
-
- xor eax,edx
- sub eax,edx
-
- add eax,x0
- mov x0_,eax
-
- jmp clip_loop
- Xmaj_x1_lo:
- // x1_ = CP_L;
- // y1_ = y0 - sgndxdy * floor ((x0-x1_)*slope+1/2);
- mov eax,_L
- mov x1_,eax
- sub eax,x0
- neg eax
-
- mul slope
- add eax,0x80000000
- adc edx,0
- mov eax,edx
-
- mov edx,sgndxdy
- not edx
-
- xor eax,edx
- sub eax,edx
-
- add eax,y0
- mov y1_,eax
-
- jmp clip_loop
- Ymaj_x1_lo:
- // x1_ = CP_L;
- // y1_ = y0 - sgndxdy * (ceil ((x0-x1_+1/2)/slope) - 1);
- mov eax,_L
- mov x1_,eax
- sub eax,x0
- neg eax
-
- mov edx,eax
- mov eax,0x80000000
- div slope
-
- cmp edx,1
- sbb eax,0
-
- mov edx,sgndxdy
- not edx
-
- xor eax,edx
- sub eax,edx
-
- add eax,y0
- mov y1_,eax
-
- jmp clip_loop
- Xmaj_x1_hi:
- // x1_ = CP_R;
- // y1_ = y0 + sgndxdy * floor ((x1_-x0)*slope+1/2);
-
- mov eax,_R
- mov x1_,eax
- sub eax,x0
-
- mul slope
- add eax,0x80000000
- adc edx,0
- mov eax,edx
-
- mov edx,sgndxdy
-
- xor eax,edx
- sub eax,edx
-
- add eax,y0
- mov y1_,eax
-
- jmp clip_loop
- Ymaj_x1_hi:
- // x1_ = CP_R;
- // y1_ = y0 + sgndxdy * (ceil ((x1_-x0+1/2)/slope) - 1);
- mov eax,_R
- mov x1_,eax
- sub eax,x0
-
- mov edx,eax
- mov eax,0x80000000
- div slope
-
- cmp edx,1
- sbb eax,0
-
- mov edx,sgndxdy
-
- xor eax,edx
- sub eax,edx
-
- add eax,y0
- mov y1_,eax
-
- jmp clip_loop
- Ymaj_y1_lo:
- // y1_ = CP_T;
- // x1_ = x0 - sgndxdy * floor ((y0-y1_)*slope+1/2);
- mov eax,_T
- mov y1_,eax
- sub eax,y0
- neg eax
-
- mul slope
- add eax,0x80000000
- adc edx,0
- mov eax,edx
-
- mov edx,sgndxdy
- not edx
-
- xor eax,edx
- sub eax,edx
-
- add eax,x0
- mov x1_,eax
-
- jmp clip_loop
- Xmaj_y1_lo:
- // y1_ = CP_T;
- // x1_ = x0 - sgndxdy * (ceil ((y0-y1_+1/2)/slope) - 1);
-
- mov eax,_T
- mov y1_,eax
- sub eax,y0
- neg eax
-
- mov edx,eax
- mov eax,0x80000000
- div slope
-
- cmp edx,1
- sbb eax,0
-
- mov edx,sgndxdy
- not edx
-
- xor eax,edx
- sub eax,edx
-
- add eax,x0
- mov x1_,eax
-
- jmp clip_loop
-
- Ymaj_y1_hi:
- // y1_ = CP_B;
- // x1_ = x0 + sgndxdy * floor ((y1_-y0)*slope+1/2);
- mov eax,_B
- mov y1_,eax
- sub eax,y0
-
- mul slope
- add eax,0x80000000
- adc edx,0
- mov eax,edx
-
- mov edx,sgndxdy
-
- xor eax,edx
- sub eax,edx
-
- add eax,x0
- mov x1_,eax
-
- jmp clip_loop
- Xmaj_y1_hi:
- // y1_ = CP_B;
- // x1_ = x0 + sgndxdy * (ceil ((y1_-y0+1/2)/slope) - 1);
- mov eax,_B
- mov y1_,eax
- sub eax,y0
-
- mov edx,eax
- mov eax,0x80000000
- div slope
-
- cmp edx,1
- sbb eax,0
-
- mov edx,sgndxdy
-
- xor eax,edx
- sub eax,edx
-
- add eax,x0
- mov x1_,eax
-
- jmp clip_loop
- #if 0
- //----------------------------------------------------------------------------
- //
- // Macros for inner loops of DRAW forms (Y major, X major, and Straight)
- //
- //----------------------------------------------------------------------------
- YM_DRAW MACRO adc_sbb
- mov [edi],al ; [adr] = pixel
- add edx,ebx ; accum += slope
- adc_sbb edi,esi ; adr += ystep (+ xstep)
- dec ecx ; count--
- ENDM
- //----------------------------------------------------------------------------
- XM_DRAW MACRO inc_dec
- mov [edi],al ; [adr] = pixel
- inc_dec edi ; adr += xstep
- add edx,ebx ; accum += slope
- jnc @F ; if accum overflowed,
- add edi,esi ; adr += ystep
- @@:
- dec ecx ; count--
- ENDM
- //----------------------------------------------------------------------------
- ST_DRAW MACRO
- mov [edi],al ; [adr] = pixel
- add edi,esi ; adr += xystep
- dec ecx ; count--
- ENDM
- //----------------------------------------------------------------------------
- //
- // Macros for inner loops of XLAT forms (Y major, X major, and Straight)
- //
- //----------------------------------------------------------------------------
- YM_XLAT MACRO adc_sbb
- mov al,[edi] ; pixel = [adr]
- xlat ; pixel = parm[pixel]
- mov [edi],al ; [adr] = pixel
- add edx,ebp ; accum += slope
- adc_sbb edi,esi ; adr += ystep (+ xstep)
- dec ecx ; count--
- ENDM
- //----------------------------------------------------------------------------
- XM_XLAT MACRO inc_dec
- mov al,[edi] ; pixel = [adr]
- xlat ; pixel = parm[pixel]
- mov [edi],al ; [adr] = pixel
- inc_dec edi ; adr += xstep
- add edx,ebp ; accum += slope
- jnc @F ; if accum overflowed,
- add edi,esi ; adr += ystep
- @@:
- dec ecx ; count--
- ENDM
- //----------------------------------------------------------------------------
- SW_XLAT MACRO
- mov al,[edi] ; pixel = [adr]
- xlat ; pixel = parm[pixel]
- mov [edi],al ; [adr] = pixel
- add edi,esi ; adr += xystep
- dec ecx ; count--
- ENDM
- //----------------------------------------------------------------------------
- #endif
- Accept:
- // calculate adr (edi),
- // address of first pixel = window_buffer + CP_W*y0 + x0
- //GET_WINDOW_ADDRESS x0_, y0_
- mov eax,y0_
- imul _W
- add eax,_A
- add eax,x0_
- mov edi,eax
- // calculate ystep (esi) = CP_W * sgn (dy)
- mov esi,_W
- xor esi,sgndy
- sub esi,sgndy
- // get slope
- mov ebx,slope
- // branch to Diagonal, Xmajor or Ymajor depending on absdx & absdy
- mov eax,absdx
- cmp eax,absdy
- je Diagonal
- jg Xmajor
- ;----------------------------------------------------------------------------
- //Ymajor:
- // calculate count (ecx) = abs (y1_ - y0_) + 1
- mov eax,y1_
- sub eax,y0_
- cdq
- xor eax,edx
- sub eax,edx
- inc eax
- mov ecx,eax
- // calculate accum (edx) = abs (y0_ - y0) * slope + 1/2
- mov eax,y0_
- sub eax,y0
- cdq
- xor eax,edx
- sub eax,edx
- mul ebx
- add eax,0x80000000
- mov edx,eax
- // branch to YmajorNegdx or fall through to YmajorPosdx depending on sgndx
- cmp sgndx,-1
- je YmajorNegdx
- //----------------------------------------------------------------------------
- //YmajorPosdx:
- cmp mode,1
- je YmPdxXlat
- jg YmPdxProc
- //----------------------------------------------------------------------------
- //YmPdxDraw:
- mov eax,parm // get line color
- YmPdxDrawLoop:
- //REPEAT LD_COPIES-1 //; repeat this code copies-1 times or 3 times!
- //YM_DRAW <adc> //; process a pixel
- mov [edi],al // [adr] = pixel
- add edx,ebx // accum += slope
- adc edi,esi // adr += ystep (+ xstep)
- dec ecx // count--
- jz YmPdxDrawDone
- //YM_DRAW <adc> //; process a pixel
- mov [edi],al // [adr] = pixel
- add edx,ebx // accum += slope
- adc edi,esi // adr += ystep (+ xstep)
- dec ecx // count--
- jz YmPdxDrawDone
- //YM_DRAW <adc> //; process a pixel
- mov [edi],al // [adr] = pixel
- add edx,ebx // accum += slope
- adc edi,esi // adr += ystep (+ xstep)
- dec ecx // count--
- jz YmPdxDrawDone
- //YM_DRAW <adc> //; process a pixel
- mov [edi],al // [adr] = pixel
- add edx,ebx // accum += slope
- adc edi,esi // adr += ystep (+ xstep)
- dec ecx // count--
- jnz YmPdxDrawLoop //; while (count)
- YmPdxDrawDone:
- jmp ReturnClipFlags //; done
- //----------------------------------------------------------------------------
- YmPdxXlat:
- mov eax,parm //; get translation table pointer
- push ebp //; preserve ebp
- mov ebp,ebx //; use ebp for slope to free up ebx
- mov ebx,eax //; table ptr must be in ebx for xlat
- YmPdxXlatLoop:
- //REPEAT LD_COPIES-1 //; repeat this code copies-1 times or 3 Times
- //YM_XLAT <adc> //; process a pixel
- mov al,[edi] //; pixel = [adr]
- xlat //; pixel = parm[pixel]
- mov [edi],al //; [adr] = pixel
- add edx,ebp //; accum += slope
- adc edi,esi //; adr += ystep (+ xstep)
- dec ecx //; count--
- jz YmPdxXlatDone
- //YM_XLAT <adc> //; process a pixel
- mov al,[edi] //; pixel = [adr]
- xlat //; pixel = parm[pixel]
- mov [edi],al //; [adr] = pixel
- add edx,ebp //; accum += slope
- adc edi,esi //; adr += ystep (+ xstep)
- dec ecx //; count--
- jz YmPdxXlatDone
- //YM_XLAT <adc> //; process a pixel
- mov al,[edi] //; pixel = [adr]
- xlat //; pixel = parm[pixel]
- mov [edi],al //; [adr] = pixel
- add edx,ebp //; accum += slope
- adc edi,esi //; adr += ystep (+ xstep)
- dec ecx //; count--
- jz YmPdxXlatDone
- //YM_XLAT <adc> //; process a pixel
- mov al,[edi] //; pixel = [adr]
- xlat //; pixel = parm[pixel]
- mov [edi],al //; [adr] = pixel
- add edx,ebp //; accum += slope
- adc edi,esi //; adr += ystep (+ xstep)
- dec ecx //; count--
- jnz YmPdxXlatLoop //; while (count)
- YmPdxXlatDone:
- pop ebp //; restore ebp
- jmp ReturnClipFlags //; done
- //----------------------------------------------------------------------------
- YmPdxProc:
- mov esi,panep // get pane pointer
- mov edi,x0_ // x (edi) = x0_ in pane coordinates
- sub edi,[esi+4] //.x0
- mov eax,y0_ // y (esi) = y0_ in pane coordinates
- sub eax,[esi+8] //.y0
- mov esi,eax
- mov eax,sgndy // ybump (eax) = (sgndy=-1) ? -1 : +1
- add eax,eax
- inc eax
- YmPdxProcLoop:
- pushad // callback (x, y)
- call parm
- popad
- add edx,ebx // accum += slope
- jnc F1 // if overflow, x++
- inc edi
- F1:
- add esi,eax // y += ybump
- dec ecx // count--
- jnz YmPdxProcLoop // while (count)
- jmp ReturnClipFlags // done
- //----------------------------------------------------------------------------
- YmajorNegdx:
- neg esi // neg_ystep (esi) = -ystep
- cmp mode,1
- je YmNdxXlat
- jg YmNdxProc
- //----------------------------------------------------------------------------
- //YmNdxDraw:
- mov eax,parm // get line color
- YmNdxDrawLoop:
- //REPEAT LD_COPIES-1 // repeat this code copies-1 times or 3 times
- //YM_DRAW <sbb> // process a pixel
- mov [edi],al //; [adr] = pixel
- add edx,ebx //; accum += slope
- sbb edi,esi //; adr += ystep (+ xstep)
- dec ecx //; count--
- jz YmNdxDrawDone
- //YM_DRAW <sbb> // process a pixel
- mov [edi],al //; [adr] = pixel
- add edx,ebx //; accum += slope
- sbb edi,esi //; adr += ystep (+ xstep)
- dec ecx //; count--
- jz YmNdxDrawDone
- //YM_DRAW <sbb> // process a pixel
- mov [edi],al //; [adr] = pixel
- add edx,ebx //; accum += slope
- sbb edi,esi //; adr += ystep (+ xstep)
- dec ecx //; count--
- jz YmNdxDrawDone
- //YM_DRAW <sbb> // process a pixel
- mov [edi],al //; [adr] = pixel
- add edx,ebx //; accum += slope
- sbb edi,esi //; adr += ystep (+ xstep)
- dec ecx //; count--
- jnz YmNdxDrawLoop // while (count)
- YmNdxDrawDone:
- jmp ReturnClipFlags // done
- //----------------------------------------------------------------------------
- YmNdxXlat:
- mov eax,parm // get translation table pointer
- push ebp // preserve ebp
- mov ebp,ebx // use ebp for slope to free up ebx
- mov ebx,eax // table ptr must be in ebx for xlat
- YmNdxXlatLoop:
- //REPEAT LD_COPIES-1 // repeat this code copies-1 times or 3 times
- //YM_XLAT <sbb> // process a pixel
- mov al,[edi] //; pixel = [adr]
- xlat //; pixel = parm[pixel]
- mov [edi],al //; [adr] = pixel
- add edx,ebp //; accum += slope
- sbb edi,esi //; adr += ystep (+ xstep)
- dec ecx //; count--
- jz YmNdxXlatDone
- //YM_XLAT <sbb> // process a pixel
- mov al,[edi] //; pixel = [adr]
- xlat //; pixel = parm[pixel]
- mov [edi],al //; [adr] = pixel
- add edx,ebp //; accum += slope
- sbb edi,esi //; adr += ystep (+ xstep)
- dec ecx //; count--
- jz YmNdxXlatDone
- //YM_XLAT <sbb> // process a pixel
- mov al,[edi] //; pixel = [adr]
- xlat //; pixel = parm[pixel]
- mov [edi],al //; [adr] = pixel
- add edx,ebp //; accum += slope
- sbb edi,esi //; adr += ystep (+ xstep)
- dec ecx //; count--
- jz YmNdxXlatDone
- //YM_XLAT <sbb> // process a pixel
- mov al,[edi] //; pixel = [adr]
- xlat //; pixel = parm[pixel]
- mov [edi],al //; [adr] = pixel
- add edx,ebp //; accum += slope
- sbb edi,esi //; adr += ystep (+ xstep)
- dec ecx //; count--
- jnz YmNdxXlatLoop // while (count)
- YmNdxXlatDone:
- pop ebp // restore ebp
- jmp ReturnClipFlags // done
- //----------------------------------------------------------------------------
- YmNdxProc:
- mov esi,panep // get pane pointer
- mov edi,x0_ // x (edi) = x0_ in pane coordinates
- sub edi,[esi+4] //.x0
- mov eax,y0_ // y (esi) = y0_ in pane coordinates
- sub eax,[esi+8] //.y0
- mov esi,eax
- mov eax,sgndy // ybump (eax) = (sgndy=-1) ? -1 : +1
- add eax,eax
- inc eax
- YmNdxProcLoop:
- pushad // callback (x, y)
- call parm
- popad
- add edx,ebx // accum += slope
- jnc F2 // if overflow, x--
- dec edi
- F2:
- add esi,eax // y += ybump
- dec ecx // count--
- jnz YmNdxProcLoop // while (count)
- jmp ReturnClipFlags // done
- //----------------------------------------------------------------------------
- Xmajor:
- // calculate count (ecx) = abs (x1_ - x0_) + 1
- mov eax,x1_
- sub eax,x0_
- cdq
- xor eax,edx
- sub eax,edx
- inc eax
- mov ecx,eax
- // calculate accum (edx) = abs (x0_ - x0) * slope + 1/2
- mov eax,x0_
- sub eax,x0
- cdq
- xor eax,edx
- sub eax,edx
- mul ebx
- add eax,0x80000000
- mov edx,eax
- // branch to XmajorNegdx or fall through to XmajorPosdx depending on sgndx
- cmp sgndx,-1
- je XmajorNegdx
- //----------------------------------------------------------------------------
- //XmajorPosdx:
- cmp mode,1
- je XmPdxXlat
- jg XmPdxProc
- //----------------------------------------------------------------------------
- //XmPdxDraw:
- mov eax,parm // get line color
-
- XmPdxDrawLoop:
- //REPEAT LD_COPIES-1 // repeat this code copies-1 times or 3 Times
- //XM_DRAW <inc> // process a pixel
- mov [edi],al // [adr] = pixel
- inc edi // adr += xstep
- add edx,ebx // accum += slope
- jnc Fa1 // if accum overflowed,
- add edi,esi // adr += ystep
- Fa1:
- dec ecx // count--
- jz XmPdxDrawDone
- //XM_DRAW <inc> // process a pixel
- mov [edi],al // [adr] = pixel
- inc edi // adr += xstep
- add edx,ebx // accum += slope
- jnc Fa2 // if accum overflowed,
- add edi,esi // adr += ystep
- Fa2:
- dec ecx // count--
- jz XmPdxDrawDone
- //XM_DRAW <inc> // process a pixel
- mov [edi],al // [adr] = pixel
- inc edi // adr += xstep
- add edx,ebx // accum += slope
- jnc Fa3 // if accum overflowed,
- add edi,esi // adr += ystep
- Fa3:
- dec ecx // count--
- jz XmPdxDrawDone
- //XM_DRAW <inc> // process a pixel
- mov [edi],al // [adr] = pixel
- inc edi // adr += xstep
- add edx,ebx // accum += slope
- jnc Fa4 // if accum overflowed,
- add edi,esi // adr += ystep
- Fa4:
- dec ecx // count--
- jnz XmPdxDrawLoop // while (count)
- XmPdxDrawDone:
- jmp ReturnClipFlags // done
- //----------------------------------------------------------------------------
- XmPdxXlat:
- mov eax,parm // get translation table pointer
- push ebp // preserve ebp
- mov ebp,ebx // use ebp for slope to free up ebx
- mov ebx,eax // table ptr must be in ebx for xlat
- XmPdxXlatLoop:
- //REPEAT LD_COPIES-1 // repeat this code copies-1 times or 3 times
- //XM_XLAT <inc> // process a pixel
- mov al,[edi] //; pixel = [adr]
- xlat //; pixel = parm[pixel]
- mov [edi],al //; [adr] = pixel
- inc edi //; adr += xstep
- add edx,ebp //; accum += slope
- jnc Fb1 //; if accum overflowed,
- add edi,esi //; adr += ystep
- Fb1:
- dec ecx //; count--
- jz XmPdxXlatDone
- //XM_XLAT <inc> // process a pixel
- mov al,[edi] //; pixel = [adr]
- xlat //; pixel = parm[pixel]
- mov [edi],al //; [adr] = pixel
- inc edi //; adr += xstep
- add edx,ebp //; accum += slope
- jnc Fb2 //; if accum overflowed,
- add edi,esi //; adr += ystep
- Fb2:
- dec ecx //; count--
- jz XmPdxXlatDone
- //XM_XLAT <inc> // process a pixel
- mov al,[edi] //; pixel = [adr]
- xlat //; pixel = parm[pixel]
- mov [edi],al //; [adr] = pixel
- inc edi //; adr += xstep
- add edx,ebp //; accum += slope
- jnc Fb3 //; if accum overflowed,
- add edi,esi //; adr += ystep
- Fb3:
- dec ecx //; count--
- jz XmPdxXlatDone
- //XM_XLAT <inc> // process a pixel
- mov al,[edi] //; pixel = [adr]
- xlat //; pixel = parm[pixel]
- mov [edi],al //; [adr] = pixel
- inc edi //; adr += xstep
- add edx,ebp //; accum += slope
- jnc Fb4 //; if accum overflowed,
- add edi,esi //; adr += ystep
- Fb4:
- dec ecx //; count--
- jnz XmPdxXlatLoop // while (count)
- XmPdxXlatDone:
- pop ebp // restore ebp
- jmp ReturnClipFlags // done
- //----------------------------------------------------------------------------
- XmPdxProc:
- mov esi,panep // get pane pointer
- mov edi,x0_ // x (edi) = x0_ in pane coordinates
- sub edi,[esi+4] //.x0
- mov eax,y0_ // y (esi) = y0_ in pane coordinates
- sub eax,[esi+8] //.y0
- mov esi,eax
- mov eax,sgndy // xbump (eax) = (sgndy=-1) ? -1 : +1
- add eax,eax
- inc eax
- XmPdxProcLoop:
- pushad // callback (x, y)
- call parm
- popad
- add edx,ebx // accum += slope
- jnc F3 // if overflow, y++
- inc esi
- F3: add edi,eax // x += xbump
- dec ecx // count--
- jnz XmPdxProcLoop // while (count)
- jmp ReturnClipFlags // done
- //----------------------------------------------------------------------------
- XmajorNegdx:
- cmp mode,1
- je XmNdxXlat
- jg XmNdxProc
- //----------------------------------------------------------------------------
- //XmNdxDraw:
- mov eax,parm // get line color
-
- XmNdxDrawLoop:
- //REPEAT LD_COPIES-1 // repeat this code copies-1 times or 3 times
- //XM_DRAW <dec> // process a pixel
- mov [edi],al //; [adr] = pixel
- dec edi //; adr += xstep
- add edx,ebx //; accum += slope
- jnc Fc1 //; if accum overflowed,
- add edi,esi //; adr += ystep
- Fc1:
- dec ecx //; count--
- jz XmNdxDrawDone
- //XM_DRAW <dec> // process a pixel
- mov [edi],al //; [adr] = pixel
- dec edi //; adr += xstep
- add edx,ebx //; accum += slope
- jnc Fc2 //; if accum overflowed,
- add edi,esi //; adr += ystep
- Fc2:
- dec ecx //; count--
- jz XmNdxDrawDone
- //XM_DRAW <dec> // process a pixel
- mov [edi],al //; [adr] = pixel
- dec edi //; adr += xstep
- add edx,ebx //; accum += slope
- jnc Fc3 //; if accum overflowed,
- add edi,esi //; adr += ystep
- Fc3:
- dec ecx //; count--
- jz XmNdxDrawDone
- //XM_DRAW <dec> // process a pixel
- mov [edi],al //; [adr] = pixel
- dec edi //; adr += xstep
- add edx,ebx //; accum += slope
- jnc Fc4 //; if accum overflowed,
- add edi,esi //; adr += ystep
- Fc4:
- dec ecx //; count--
- jnz XmNdxDrawLoop // while (count)
- XmNdxDrawDone:
- jmp ReturnClipFlags // done
- //----------------------------------------------------------------------------
- XmNdxXlat:
- mov eax,parm // get translation table pointer
- push ebp // preserve ebp
- mov ebp,ebx // use ebp for slope to free up ebx
- mov ebx,eax // table ptr must be in ebx for xlat
- XmNdxXlatLoop:
- //REPEAT LD_COPIES-1 // repeat this code copies-1 times or 3 Times
- //XM_XLAT <dec> // process a pixel
- mov al,[edi] //; pixel = [adr]
- xlat //; pixel = parm[pixel]
- mov [edi],al //; [adr] = pixel
- dec edi //; adr += xstep
- add edx,ebp //; accum += slope
- jnc Fd1 //; if accum overflowed,
- add edi,esi //; adr += ystep
- Fd1:
- dec ecx //; count--
- jz XmNdxXlatDone
- //XM_XLAT <dec> // process a pixel
- mov al,[edi] //; pixel = [adr]
- xlat //; pixel = parm[pixel]
- mov [edi],al //; [adr] = pixel
- dec edi //; adr += xstep
- add edx,ebp //; accum += slope
- jnc Fd2 //; if accum overflowed,
- add edi,esi //; adr += ystep
- Fd2:
- dec ecx //; count--
- jz XmNdxXlatDone
- //XM_XLAT <dec> // process a pixel
- mov al,[edi] //; pixel = [adr]
- xlat //; pixel = parm[pixel]
- mov [edi],al //; [adr] = pixel
- dec edi //; adr += xstep
- add edx,ebp //; accum += slope
- jnc Fd3 //; if accum overflowed,
- add edi,esi //; adr += ystep
- Fd3:
- dec ecx //; count--
- jz XmNdxXlatDone
- //XM_XLAT <dec> // process a pixel
- mov al,[edi] //; pixel = [adr]
- xlat //; pixel = parm[pixel]
- mov [edi],al //; [adr] = pixel
- dec edi //; adr += xstep
- add edx,ebp //; accum += slope
- jnc Fd4 //; if accum overflowed,
- add edi,esi //; adr += ystep
- Fd4:
- dec ecx //; count--
- jnz XmNdxXlatLoop // while (count)
- XmNdxXlatDone:
- pop ebp // restore ebp
- jmp ReturnClipFlags // done
- //----------------------------------------------------------------------------
- XmNdxProc:
- mov esi,panep // get pane pointer
- mov edi,x0_ // x (edi) = x0_ in pane coordinates
- sub edi,[esi+4] //.x0
- mov eax,y0_ // y (esi) = y0_ in pane coordinates
- sub eax,[esi+8] //.y0
- mov esi,eax
- mov eax,sgndy // xbump (eax) = (sgndy=-1) ? -1 : +1
- add eax,eax
- inc eax
- XmNdxProcLoop:
- pushad // callback (x, y)
- call parm
- popad
- add edx,ebx // accum += slope
- jnc F4 // if overflow, y--
- dec esi
- F4: add edi,eax // x += xbump
- dec ecx // count--
- jnz XmNdxProcLoop // while (count)
- jmp ReturnClipFlags // done
- //----------------------------------------------------------------------------
- Vertical:
- // reject if line is left or right of pane
- mov eax,x0
- cmp eax,_L
- jl ReturnReject
- cmp eax,_R
- jg ReturnReject
- // reject if line is above plane
- mov eax,y0
- cmp eax,y1
- jg around1a1
- mov eax,y1
- around1a1:
- cmp eax,_T
- jl ReturnReject
- // reject if line is below plane
- mov eax,y0
- cmp eax,y1
- jl around1b1
- mov eax,y1
- around1b1:
- cmp eax,_B
- jg ReturnReject
- // clip y0, clip y1
- mov eax,y0
- cmp eax,_T
- jg around2a1
- mov eax,_T
- around2a1:
- cmp eax,_B
- jg around2b1
- mov eax,_B
- around2b1:
- mov y0_,eax
- mov eax,y1
- cmp eax,_T
- jg around3a1
- mov eax,_T
- around3a1:
- cmp eax,_B
- jg around3b1
- mov eax,_B
- around3b1:
- mov y1_,eax
- mov eax,x0
- mov x0_,eax
- // calculate ystep (esi)
- mov esi,_W
- xor esi,sgndy
- sub esi,sgndy
- // calculate count (ecx) = abs(y1-y0) + 1
- mov eax,y1_
- sub eax,y0_
- cdq
- xor eax,edx
- sub eax,edx
- mov ecx,eax
- inc ecx
- jmp Straight
- //---------------------------------------------------------------------------
- Horizontal:
- // reject if line is above or below pane
- mov eax,y0
- cmp eax,_T
- jl ReturnReject
- cmp eax,_B
- jg ReturnReject
- // reject if line is left of pane
- mov eax,x0
- cmp eax,x1
- jg around1a
- mov eax,x1
- around1a:
- cmp eax,_L
- jl ReturnReject
- // reject if line is right of pane
- mov eax,x0
- cmp eax,x1
- jl around1b
- mov eax,x1
- around1b:
- cmp eax,_R
- jg ReturnReject
- // clip x0, clip x1
- mov eax,x0
- cmp eax,_L
- jg around2a
- mov eax,_L
- around2a:
- cmp eax,_R
- jl around2b
- mov eax,_R
- around2b:
- mov x0_,eax
- mov eax,x1
- cmp eax,_L
- jg around3a
- mov eax,_L
- around3a:
- cmp eax,_R
- jl around3b
- mov eax,_R
- around3b:
- mov x1_,eax
- mov eax,y0
- mov y0_,eax
- // calculate xstep (esi)
- mov esi,sgndx
- inc esi
- or esi,sgndx
- // calculate count (ecx) = abs(x1-x0) + 1
- mov eax,x1_
- sub eax,x0_
- cdq
- xor eax,edx
- sub eax,edx
- mov ecx,eax
- inc ecx
- jmp Straight
- ;----------------------------------------------------------------------------
- Diagonal:
- // calculate xystep (esi)
- mov esi,_W
- xor esi,sgndy
- sub esi,sgndy
- mov eax,sgndx
- inc eax
- or eax,sgndx
- add esi,eax
- // calculate count (ecx) = abs(x1-x0) + 1
- mov eax,x1_
- sub eax,x0_
- cdq
- xor eax,edx
- sub eax,edx
- mov ecx,eax
- inc ecx
- //----------------------------------------------------------------------------
- Straight:
- // calculate adr (edi), address of first pixel = window_buffer + CP_W*y0 + x0
- //GET_WINDOW_ADDRESS x0_, y0_
- mov eax,y0_
- imul _W
- add eax,_A
- add eax,x0_
- mov edi,eax
- // draw the line with a color, a translation table, or a callback function
- cmp mode,1
- je StraightXlat
- jg StraightProc
- //----------------------------------------------------------------------------
- //StraightDraw:
- mov eax,parm // get line color
- StraightLoop:
- //REPEAT LD_COPIES-1 // repeat code copies-1 times or 3 Times
- //ST_DRAW // process a pixel
- mov [edi],al // [adr] = pixel
- add edi,esi // adr += xystep
- dec ecx // count--
- jz StraightDone
- //ST_DRAW // process a pixel
- mov [edi],al // [adr] = pixel
- add edi,esi // adr += xystep
- dec ecx // count--
- jz StraightDone
- //ST_DRAW // process a pixel
- mov [edi],al // [adr] = pixel
- add edi,esi // adr += xystep
- dec ecx // count--
- jz StraightDone
- //ST_DRAW // process a pixel
- mov [edi],al // [adr] = pixel
- add edi,esi // adr += xystep
- dec ecx // count--
- jnz StraightLoop // while (count)
- StraightDone:
- jmp ReturnClipFlags // done
- //----------------------------------------------------------------------------
- StraightXlat:
- mov ebx,parm // get pointer to translation table
- StraightXlatLoop:
- //REPEAT LD_COPIES-1 // repeat code copies-1 times or 3 Times
- //SW_XLAT // process a pixel
- mov al,[edi] //; pixel = [adr]
- xlat //; pixel = parm[pixel]
- mov [edi],al //; [adr] = pixel
- add edi,esi //; adr += xystep
- dec ecx //; count--
- jz StraightXlatDone
- //SW_XLAT // process a pixel
- mov al,[edi] //; pixel = [adr]
- xlat //; pixel = parm[pixel]
- mov [edi],al //; [adr] = pixel
- add edi,esi //; adr += xystep
- dec ecx //; count--
- jz StraightXlatDone
- //SW_XLAT // process a pixel
- mov al,[edi] //; pixel = [adr]
- xlat //; pixel = parm[pixel]
- mov [edi],al //; [adr] = pixel
- add edi,esi //; adr += xystep
- dec ecx //; count--
- jz StraightXlatDone
- //SW_XLAT // process a pixel
- mov al,[edi] //; pixel = [adr]
- xlat //; pixel = parm[pixel]
- mov [edi],al //; [adr] = pixel
- add edi,esi //; adr += xystep
- dec ecx //; count--
- jnz StraightXlatLoop // while (count)
- StraightXlatDone:
- jmp ReturnClipFlags // done
- //---------------------------------------------------------------------------
- StraightProc:
- mov esi,panep // get pane pointer
- mov edi,x0_ // x (edi) = x0_ in pane coordinates
- sub edi,[esi+4] //.x0
- mov eax,y0_ // y (esi) = y0_ in pane coordinates
- sub eax,[esi+8] //.y0
- mov esi,eax
- xor eax,eax // ybump (eax) = sgn (_dy)
- test _dy,-1
- setnz al
- or eax,sgndy
- xor ebx,ebx // xbump (ebx) = sgn (_dx)
- test _dx,-1
- setnz bl
- or ebx,sgndx
- StraightProcLoop:
- pushad // callback (x, y)
- call parm
- popad
- add esi,eax // y += ybump
- add edi,ebx // x += xbump
- dec ecx // count--
- jnz StraightProcLoop // while (count)
- jmp ReturnClipFlags // done
- // return error code:
- //
- // -2: pane was malformed (or completely off its window)
- // -1: window was malformed
- // 0: line was accepted
- // 1: line was clipped
- // 2: line was rejected
- ReturnClipFlags:
- xor eax,eax
- cmp clip_flags,1
- setae al
- jmp exit
- ReturnReject:
- mov eax,2
- jmp exit
- exit:
- mov lineResult,eax
- }
- return lineResult;
- }
- //----------------------------------------------------------------------------
- //
- // int cdecl VFX_pixel_write (PANE *panep, int x, int y, UBYTE color)
- //
- // This function writes a single pixel.
- //
- // The panep parameter specifies the pane containing the pixel to be written.
- // The x and y parameters specify the pixel coordinates.
- // The color parameter specifies the color to write to the pixel.
- //
- // Return values:
- //
- // 0..255:
- // Pixel value prior to write.
- //
- // -1: Bad window.
- // The height or width of the pane's window is less than one.
- //
- // -2: Bad pane.
- // The height or width of the pane is less than one.
- //
- // -3: Off pane.
- // The specified pixel is off the pane.
- //
- //----------------------------------------------------------------------------
- LONG VFX_pixel_write (PANE *panep, LONG x, LONG y, ULONG color)
- {
- long _L; //Leftmost pixel in Window coord.
- long _T; //Top
- long _R; //Right
- long _B; //Bottom
-
- MemoryPtr _A; //Base address of Clipped Pane
- long _W; //Width of underlying window (bytes)
-
- long _CX; //Window x coord. = Pane x coord. + CP_CX
- long _CY; //Window y coord. = Pane x coord. + CP_CY
- int result = 0;
-
- __asm
- {
- cld
- }
- //Clip Pane to Window Routine
- // get panep (esi)
- // windowp (ebx) = panep->win
- //ASSUME esi:PPANE
- //ASSUME ebx:PWIN
- __asm
- {
- mov esi,panep
- mov ebx,[esi] //This is the Window Pointer
- // _W = windowp->wnd_x1 + 1
- // if _W <= 0, return bad window
-
- mov eax,[ebx+4] //X1 Window Coord
- inc eax
- mov _W,eax
- jle ReturnBadWindow
-
- // ecx = Ysize = windowp->wnd_y1 + 1
- // if <= 0, return bad window
- mov eax,[ebx+8] //y1 Window Coord
- inc eax
- mov ecx,eax
- jle ReturnBadWindow
- // clip pane to window:
- // pane_x0 = max (pane->x0, 0)
- // pane_y0 = max (pane->y0, 0)
- // pane_x1 = min (pane->x1, _W - 1)
- // pane_y1 = min (pane->x1, (Ysize=ecx) - 1)
- mov eax,[esi+4] //x0 in Pane Coord
- mov _CX,eax
- cmp eax,0
- jg around1
- mov eax,0
- around1:
- mov _L,eax
-
- mov eax,[esi+8] //y0 in Pane Coord
- mov _CY,eax
- cmp eax,0
- jg around2
- mov eax,0
- around2:
- mov _T,eax
-
- mov eax,[esi+12] //X1 in Pane Coord
- mov edx,_W
- dec edx
- cmp eax,edx
- jl around3
- mov eax,edx
- around3:
- mov _R,eax
-
- mov eax,[esi+16] //y1 in Pane Coord
- mov edx,ecx
- dec edx
- cmp eax,edx
- jl around4
- mov eax,edx
- around4:
- mov _B,eax
- // exit if pane is malformed or completely off window:
- // if _B < &vname&_T, return bad pane
- // if _R < &vname&_L, return bad pane
- mov eax,_R
- cmp eax,_L
- jl ReturnBadPane
-
- mov eax,_B
- cmp eax,_T
- jl ReturnBadPane
- mov eax,[ebx] //Buffer in Window
- mov _A,eax
- jmp exit1
- ReturnBadWindow:
- mov eax,-1
- jmp exit1
- }
- __asm
- {
- ReturnBadPane:
- mov eax,-2
- }
- exit1:
- __asm
- {
- // transform x & y to window coord's
- mov ecx,x
- mov ebx,y
- //CONVERT_REG_PAIR_PANE_TO_WINDOW ecx, ebx
-
- add ecx,_CX
- add ebx,_CY
- // clip pixel to pane
-
- cmp ecx,_L
- jl ReturnOffPane
- cmp ecx,_R
- jg ReturnOffPane
- cmp ebx,_T
- jl ReturnOffPane
- cmp ebx,_B
- jg ReturnOffPane
- // adr (ebx) = window->buffer + CP_W * y + x
- //GET_WINDOW_ADDRESS x0_, y0_
- mov eax,ebx
- imul _W
- add eax,_A
- add eax,ecx
- mov edi,eax
- mov ebx,eax
- // write the pixel
- mov dl,BYTE PTR color
- mov [ebx],dl
- // return prior_value
- ret
- // error returns
- ReturnOffPane:
- mov eax,-3
- ret
-
- }
-
- return(result);
- }
- //----------------------------------------------------------------------------
- //
- // int cdecl VFX_pixel_read (PANE *panep, int x, int y)
- //
- // This function reads a single pixel.
- //
- // The panep parameter specifies the pane containing the pixel to be written.
- // The x and y parameters specify the pixel coordinates.
- //
- // Return values:
- //
- // 0..255:
- // Pixel value.
- //
- // -1: Bad window.
- // The height or width of the pane's window is less than one.
- //
- // -2: Bad pane.
- // The height or width of the pane is less than one.
- //
- // -3: Off pane.
- // The specified pixel is off the pane.
- //
- //---------------------------------------------------------------------------
- LONG VFX_pixel_read (PANE *panep, LONG x, LONG y)
- {
- long _L; //Leftmost pixel in Window coord.
- long _T; //Top
- long _R; //Right
- long _B; //Bottom
-
- MemoryPtr _A; //Base address of Clipped Pane
- long _W; //Width of underlying window (bytes)
-
- long _CX; //Window x coord. = Pane x coord. + CP_CX
- long _CY; //Window y coord. = Pane x coord. + CP_CY
- int result = 0;
-
- __asm
- {
- cld
- }
- //Clip Pane to Window Routine
- // get panep (esi)
- // windowp (ebx) = panep->win
- //ASSUME esi:PPANE
- //ASSUME ebx:PWIN
- __asm
- {
- mov esi,panep
- mov ebx,[esi] //This is the Window Pointer
- // _W = windowp->wnd_x1 + 1
- // if _W <= 0, return bad window
-
- mov eax,[ebx+4] //X1 Window Coord
- inc eax
- mov _W,eax
- jle ReturnBadWindow
-
- // ecx = Ysize = windowp->wnd_y1 + 1
- // if <= 0, return bad window
- mov eax,[ebx+8] //y1 Window Coord
- inc eax
- mov ecx,eax
- jle ReturnBadWindow
- // clip pane to window:
- // pane_x0 = max (pane->x0, 0)
- // pane_y0 = max (pane->y0, 0)
- // pane_x1 = min (pane->x1, _W - 1)
- // pane_y1 = min (pane->x1, (Ysize=ecx) - 1)
- mov eax,[esi+4] //x0 in Pane Coord
- mov _CX,eax
- cmp eax,0
- jg around1
- mov eax,0
- around1:
- mov _L,eax
-
- mov eax,[esi+8] //y0 in Pane Coord
- mov _CY,eax
- cmp eax,0
- jg around2
- mov eax,0
- around2:
- mov _T,eax
-
- mov eax,[esi+12] //X1 in Pane Coord
- mov edx,_W
- dec edx
- cmp eax,edx
- jl around3
- mov eax,edx
- around3:
- mov _R,eax
-
- mov eax,[esi+16] //y1 in Pane Coord
- mov edx,ecx
- dec edx
- cmp eax,edx
- jl around4
- mov eax,edx
- around4:
- mov _B,eax
- // exit if pane is malformed or completely off window:
- // if _B < &vname&_T, return bad pane
- // if _R < &vname&_L, return bad pane
- mov eax,_R
- cmp eax,_L
- jl ReturnBadPane
-
- mov eax,_B
- cmp eax,_T
- jl ReturnBadPane
- mov eax,[ebx] //Buffer in Window
- mov _A,eax
- jmp exit1
- ReturnBadWindow:
- mov eax,-1
- jmp exit1
- }
- __asm
- {
- ReturnBadPane:
- mov eax,-2
- }
- exit1:
- __asm
- {
- // transform x & y to window coord's
- mov ecx,x
- mov ebx,y
- //CONVERT_REG_PAIR_PANE_TO_WINDOW ecx, ebx
-
- add ecx,_CX
- add ebx,_CY
- // clip pixel to pane
-
- cmp ecx,_L
- jl ReturnOffPane
- cmp ecx,_R
- jg ReturnOffPane
- cmp ebx,_T
- jl ReturnOffPane
- cmp ebx,_B
- jg ReturnOffPane
- // adr (ebx) = window->buffer + CP_W * y + x
- //GET_WINDOW_ADDRESS x0_, y0_
- mov eax,ebx
- imul _W
- add eax,_A
- add eax,ecx
- mov edi,eax
- mov ebx,eax
- // read and return the pixel
-
- xor eax,eax
- mov al,[ebx]
- ret
- // error returns
- ReturnOffPane:
- mov eax,-3
- mov result, eax
- ret
- }
-
- return(result);
- }
|