123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401 |
- #include "vfx.h"
- extern char AlphaTable[256*256];
- extern enum { CPU_UNKNOWN, CPU_PENTIUM, CPU_MMX } Processor;
- extern void memfill(void *Dest,int Length);
- extern void memclear(void *Dest,int Length);
- void CopySprite( PANE *pane, void *texture, int X, int Y, int Width, int Height, int Flip, int Shrink );
- void AG_shape_fill (PANE *pane, void *shape_table,LONG shape_number, LONG hotX, LONG hotY);
- void AG_shape_draw (PANE *pane, void *shape_table,LONG shape_number, LONG hotX, LONG hotY);
- void AG_shape_translate_fill (PANE *pane, void *shape_table,LONG shape_number, LONG hotX, LONG hotY);
- extern unsigned int lookaside;
- int SqrtCount=0;
- typedef unsigned int DWORD;
- typedef struct
- {
- DWORD bounds;
- DWORD origin;
- DWORD xmin;
- DWORD ymin;
- DWORD xmax;
- DWORD ymax;
- } SHAPEHEADER;
- //
- // Sprite format
- //
- //
- // Marker.
- // 0 End of line
- // 1 Skip next bytes
- // Bit 0 = 0 Repeat next byte [7654321] times
- // Bit 0 = 1 String packet [7654321] bytes
- //
- static unsigned int SourceWidth,tWidth,tHeight,DestWidth; // Used for code optimizing
- static _int64 xmask=-1;
- static unsigned int tempXmax,tempXmin;
- static unsigned int minX,minY,maxY,maxX,SkipLeft,NewWidth,StartofLine,StartofClip,EndofClip;
- static unsigned int lines,paneX0,paneX1,paneY0,paneY1,SourcePointer,DestPointer;
- static signed int X,Y,X1;
- static PANE tempPANE;
- static WINDOW tempWINDOW;
- void AG_shape_transform( PANE *globalPane, void *shapeTable, LONG frameNum, LONG hotX, LONG hotY, void *tempBuffer, LONG reverse, LONG scaleUp )
- {
- _asm{
- mov esi,shapeTable
- mov eax,frameNum
- mov ecx,[esi+eax*8+8]
- mov eax,[esi+ecx+SHAPEHEADER.xmax]
- mov ebx,[esi+ecx+SHAPEHEADER.xmin]
- mov X1,eax
- mov X,ebx
- sub eax,ebx
- inc eax
- mov maxX,eax
- mov eax,[esi+ecx+SHAPEHEADER.ymax]
- mov ebx,[esi+ecx+SHAPEHEADER.ymin]
- mov Y,ebx
- sub eax,ebx
- inc eax
- mov maxY,eax
- }
- tempWINDOW.buffer=(UBYTE*)tempBuffer;
- tempWINDOW.x_max=maxX-1;
- tempWINDOW.y_max=maxY-1;
- tempPANE.window=&tempWINDOW;
- tempPANE.x0=0;
- tempPANE.y0=0;
- tempPANE.x1=maxX-1;
- tempPANE.y1=maxY-1;
- //-------------------------------------------------------------------------------------
- // Some armor here. We have still have a bug somewhere that trashes the shape by
- // the time it gets here. Armor against for now and make Fatal to try to track down!
- #define MAX_X 360
- #define MAX_Y 360
- if ((maxX * maxY) >= (MAX_Y * MAX_X))
- {
- return;
- }
- //-------------------------------------------------------------------------------------
- memclear(tempBuffer,maxX*maxY);
- AG_shape_draw ( &tempPANE, shapeTable, frameNum, -X, -Y );
- if(scaleUp)
- {
- if(reverse)
- CopySprite( globalPane, tempBuffer, hotX-X1, hotY+Y, maxX, maxY, reverse, scaleUp );
- else
- CopySprite( globalPane, tempBuffer, hotX+X, hotY+Y, maxX, maxY, reverse, scaleUp );
- }
- else
- {
- if(reverse)
- CopySprite( globalPane, tempBuffer, hotX-(X1>>1), hotY+(Y>>1), maxX, maxY, reverse, scaleUp );
- else
- CopySprite( globalPane, tempBuffer, hotX+(X>>1), hotY+(Y>>1), maxX, maxY, reverse, scaleUp );
- }
- }
- void AG_shape_translate_transform( PANE *globalPane, void *shapeTable, LONG frameNum, LONG hotX, LONG hotY,void *tempBuffer, LONG reverse, LONG scaleUp )
- {
- _asm{
- mov esi,shapeTable
- mov eax,frameNum
- mov ecx,[esi+eax*8+8]
- mov eax,[esi+ecx+SHAPEHEADER.xmax]
- mov ebx,[esi+ecx+SHAPEHEADER.xmin]
- mov X1,eax
- mov X,ebx
- sub eax,ebx
- inc eax
- mov maxX,eax
- mov eax,[esi+ecx+SHAPEHEADER.ymax]
- mov ebx,[esi+ecx+SHAPEHEADER.ymin]
- mov Y,ebx
- sub eax,ebx
- inc eax
- mov maxY,eax
- }
- tempWINDOW.buffer=(UBYTE*)tempBuffer;
- tempWINDOW.x_max=maxX-1;
- tempWINDOW.y_max=maxY-1;
- tempPANE.window=&tempWINDOW;
- tempPANE.x0=0;
- tempPANE.y0=0;
- tempPANE.x1=maxX-1;
- tempPANE.y1=maxY-1;
- //-------------------------------------------------------------------------------------
- // Some armor here. We have still have a bug somewhere that trashes the shape by
- // the time it gets here. Armor against for now and make Fatal to try to track down!
- #define MAX_X 360
- #define MAX_Y 360
- if ((maxX * maxY) >= (MAX_Y * MAX_X))
- {
- return;
- }
- //-------------------------------------------------------------------------------------
- memclear(tempBuffer,maxX*maxY);
- AG_shape_translate_fill ( &tempPANE, shapeTable, frameNum, -X, -Y );
- if(scaleUp)
- {
- if(reverse)
- CopySprite( globalPane, tempBuffer, hotX-X1, hotY+Y, maxX, maxY, reverse, scaleUp );
- else
- CopySprite( globalPane, tempBuffer, hotX+X, hotY+Y, maxX, maxY, reverse, scaleUp );
- }
- else
- {
- if(reverse)
- CopySprite( globalPane, tempBuffer, hotX-(X1>>1), hotY+(Y>>1), maxX, maxY, reverse, scaleUp );
- else
- CopySprite( globalPane, tempBuffer, hotX+(X>>1), hotY+(Y>>1), maxX, maxY, reverse, scaleUp );
- }
- }
- void CopySprite( PANE *pane, void *texture, int X, int Y, int Width, int Height, int Flip, int ScaleUp )
- {
- DestWidth = 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)DestWidth) ? pane->window->x_max : pane->x1;
- long paneY1 = (pane->y1 >= (pane->window->y_max+1)) ? pane->window->y_max : pane->y1;
- X+=paneX0;
- Y+=paneY0;
- SourcePointer = (unsigned int)texture;
- SourceWidth=Width;
-
- if( X<paneX0 )
- {
- if( ScaleUp )
- {
- Width-=paneX0-X;
- if(Flip) // Zoomed IN
- SourcePointer-=paneX0-X;
- else
- SourcePointer+=paneX0-X;
- }
- else
- {
- Width-=(paneX0-X)*2;
- if(Flip) // Zoomed OUT
- SourcePointer-=(paneX0-X)*2;
- else
- SourcePointer+=(paneX0-X)*2;
- }
-
- X=paneX0;
- }
- if( Y<paneY0 )
- {
- if( ScaleUp )
- {
- Height-=paneY0-Y;
- SourcePointer+=(paneY0-Y)*Width;
- Y=paneY0;
- }
- else
- {
- Height-=(paneY0-Y)*2;
- SourcePointer+=((paneY0-Y)*2)*Width;
- Y=paneY0;
- }
- }
-
- if( ScaleUp )
- {
- if( X+Width > (paneX1+1) )
- {
- Width= paneX1+1-X;
- }
- }
- else
- {
- if( X+(Width>>1) > (paneX1+1) )
- {
- Width= (paneX1+1-X)<<1;
- }
- }
- if( ScaleUp )
- {
- if( Y+Height > (paneY1+1) )
- Height= paneY1+1-Y;
- }
- else
- {
- if( Y+(Height>>1) > (paneY1+1) )
- Height= (paneY1+1-Y)<<1;
- }
- if ( ( X >= paneX1 ) ||
- ( Y >= paneY1 ) ||
- ( X <= (paneX0 - Width)) ||
- ( Y <= (paneY0 - Height)) ||
- (Width<=0) ||
- (Height<=0))
- return;
- DestPointer = (unsigned int)pane->window->buffer + X + Y*DestWidth;
- tWidth=Width;
- tHeight=Height;
- _asm{
- push ebp
- mov eax,Flip
- mov ebx,ScaleUp
-
- test eax,eax
- jnz DoFlip
- test ebx,ebx
- jnz UnFlipNormal
- ;
- ; Not Flipped, Shrunk
- ;
- mov ebx,tHeight
- mov edi,DestPointer
- mov esi,SourcePointer
- mov ebp,tWidth
- shr ebx,1
- jz Done
- shr ebp,1
- jz Done
- xor eax,eax
- mov edx,ebp
- tl0:
- mov al,[edi]
- inc edi
- mov ah,[esi]
- add esi,2
- mov cl,AlphaTable[eax]
- dec ebp
- mov [edi-1],cl
- jnz tl0
- mov ecx,DestWidth
- sub esi,edx
- sub esi,edx
- add edi,ecx
- sub edi,edx
- mov ecx,SourceWidth
- mov ebp,edx
- dec ebx
- lea esi,[esi+ecx*2]
- jnz tl0
- jmp Done
- ;
- ; Not flipped, not shrunk
- ;
- UnFlipNormal:
- mov edi,DestPointer
- mov esi,SourcePointer
- mov ebx,tHeight
- mov ebp,tWidth
- xor eax,eax
- mov edx,ebp
- tl1:
- mov al,[edi]
- inc edi
- mov ah,[esi]
- inc esi
- cmp ah,0
- je SKIPME1
- //mov cl,AlphaTable[eax]
- mov [edi-1],ah
- SKIPME1:
- dec ebp
- jnz tl1
- mov ecx,DestWidth
- sub edi,edx
- add edi,ecx
- mov ebp,edx
- sub esi,edx
- mov ecx,SourceWidth
- add esi,ecx
- dec ebx
- jnz tl1
- jmp Done
- DoFlip:
- test ebx,ebx
- jnz FlipNormal
- ;
- ; Flipped, Shrunk
- ;
- mov ebp,tWidth
- mov ebx,tHeight
- shr ebp,1
- jz Done
- shr ebx,1
- jz Done
- mov eax,SourceWidth
- mov esi,SourcePointer
- mov edi,DestPointer
- mov edx,ebp
- lea esi,[esi+eax*2-1]
- xor eax,eax
- tl2:
- mov al,[edi]
- inc edi
- mov ah,[esi]
- sub esi,2
- mov cl,AlphaTable[eax]
- dec ebp
- mov [edi-1],cl
- jnz tl2
- mov ecx,DestWidth
- mov ebp,edx
- add esi,edx
- add edi,ecx
- add esi,edx
- mov ecx,SourceWidth
- sub edi,edx
- dec ebx
- lea esi,[esi+ecx*2]
- jnz tl2
- jmp Done
- ;
- ; Flipped, not shrunk
- ;
- FlipNormal:
- mov eax,SourceWidth
- mov esi,SourcePointer
- mov edi,DestPointer
- mov ebp,tWidth
- mov ebx,tHeight
- lea esi,[esi+eax-1]
- xor eax,eax
- mov edx,ebp
- tl3:
- mov al,[edi]
- inc edi
- mov ah,[esi]
- dec esi
- cmp ah, 0
- je SKIPME2
- //mov cl,AlphaTable[eax]
- mov [edi-1],ah
- SKIPME2:
- dec ebp
- jnz tl3
- sub edi,edx
- mov ecx,DestWidth
- mov ebp,edx
- add edi,ecx
- mov ecx,SourceWidth
- add esi,edx
- add esi,ecx
- dec ebx
- jnz tl3
- done:
- pop ebp
- }
- return;
- }
- /*
- ;
- ; int cdecl VFX_shape_draw (PANE *panep, void *shape_table,
- ; long shape_number,int hotX, int hotY)
- ;
- ; This function clips and draws a shape to a pane.
- ;
- ; The panep parameter specifies the pane.
- ;
- ; The shape parameter specifies the shape, which must be in VFX Shape format.
- ;
- ; The hotX and hotY parameters specify the location where the shape is to be
- ; drawn. The shape's hot spot will end up at the specified location.
- ;
- */
- void AG_shape_fill (PANE *pane, void *shape_table,LONG shape_number, LONG hotX, LONG hotY)
- {
- _asm{
- mov edi,pane
- nop
- ;
- ; Clip left and right of clipping window
- ;
- mov ecx,[edi+PANE.x0]
- mov edx,[edi+PANE.y0]
- mov ebx,ecx
- mov eax,edx
- sar ebx,31
- xor eax,-1
- sar eax,31 ; If less than 0, make 0
- xor ebx,-1
- and ecx,ebx
- and edx,eax
- mov paneX0,ecx
- mov paneY0,edx
- ;
- ; Clip top and bottom of clipping window
- ;
- mov ecx,[edi+PANE.x1]
- mov edx,[edi+PANE.y1]
- mov edi,[edi+PANE.window]
- mov esi,shape_table
- mov eax,[edi+WINDOW.x_max]
- xor ebx,ebx
- inc eax
- nop
- sub ecx,eax
- mov DestWidth,eax
- setge bl
- dec ebx ; if ecx is less than eax, load ecx with eax
- nop
- and ecx,ebx
- mov ebx,[edi+WINDOW.y_max]
- add ecx,eax
- inc ebx
- xor eax,eax
- sub edx,ebx
- setge al
- dec eax
- mov paneX1,ecx
-
- and edx,eax
- mov eax,shape_number
- add edx,ebx
- mov ebx,paneY0
- ;
- ; paneX0,Y0 to PaneX1,Y1 are 0,0 -> 639,479 or window size to render too
- ;
- mov ecx,[esi+eax*8+8] ; ESI now points to start of sprite data
- mov paneY1,edx
- lea esi,[esi+ecx+SIZE SHAPEHEADER]
- mov edx,hotY
- mov ecx,[esi+SHAPEHEADER.xmax-SIZE SHAPEHEADER]
- mov eax,[esi+SHAPEHEADER.xmin-SIZE SHAPEHEADER]
- mov tempXmax,ecx ; Store Xmax and Xmin
- mov tempXmin,eax
- mov ecx,[esi+SHAPEHEADER.ymax-SIZE SHAPEHEADER]
- mov eax,[esi+SHAPEHEADER.ymin-SIZE SHAPEHEADER]
- sub ecx,eax ; ecx = Height of sprite
- add eax,edx ; eax = top line
- inc ecx ; Add one line
- nop
- ;
- ; Now check for lines off the top of the clipping window
- ;
- cmp eax,ebx
- jl ClippedTop
- ;
- ; Now check for lines off the bottom of the clipping window
- ;
- rw5:
- lea ebx,[eax+ecx-1] ; ebx=Last Line
- nop
- sub ebx,paneY1 ; Check to see if off bottom
- ja ClippedBottom
- rw6:
- mov lines,ecx ; eax still equals top line
- ;
- ; Now check clipping in X
- ;
- mov ebx,tempXmax
- mov ecx,tempXmin
- mov edx,paneX0
- sub ebx,ecx ; ebx = Width of sprite
- add ecx,hotX ; ecx = offset to left edge
- cmp ecx,edx ; Is sprite off left edge of screen?
- jl ClippedLeft
- lea edx,[ebx+ecx-1]
- mov edi,[edi+WINDOW.buffer] ; edi points to top left of buffer
- sub edx,paneX1
- jnbe ClippedRight
- ;
- ; Work out screen position
- ;
- //NowDraw:
- imul DestWidth
- add eax,ecx
- xor ecx,ecx
- add edi,eax
- mov StartofLine,edi
- ;
- ;
- ; Main drawing loop
- ;
- ;
- lineLoop:
- mov al,[esi]
- inc esi
- shr al,1
- ja RunPacket
- jnz StringPacket
- jnc EndPacket
- //SkipPacket:
- xor ecx,ecx
- mov al,[esi]
- inc esi
- xor cl,cl
- rp1a:
- mov [edi],cl ;Fill with 0 instead of skipping
- inc edi
- dec al
- jnz rp1a
- jmp lineLoop
- jmp RunPacket ; Alignement problem with rp1 otherwise
- RunPacket:
- mov cl,[esi]
- inc esi
- rp1:
- mov [edi],cl
- inc edi
- dec al
- jnz rp1
- jmp lineLoop
- StringPacket:
- //
- // 17 cycles / 8 bytes - 2.125 per byte
- //
- sub al,8
- jc sp2
- sp1:
- mov ecx,[esi]
- mov ebx,[esi+4]
- mov [edi],ecx
- mov [edi+4],ebx
- add esi,8
- add edi,8
- sub al,8
- jnc sp1
- sp2:
- add al,8
- jz lineLoop
- sp3:
- mov cl,[esi]
- inc esi
- mov [edi],cl
- inc edi
- dec al
- jnz sp3
- jmp lineLoop
- EndPacket:
- mov edx,DestWidth
- mov edi,StartofLine
- add edi,edx
- mov edx,lines
- dec edx
- mov StartofLine,edi
- mov lines,edx
- jnz lineLoop
- jmp Exit
- ;
- ;
- ; Lines are clipped off the bottom of the clip window
- ;
- ;
- ClippedBottom:
- sub ecx,ebx ; Remove lines that go off bottom
- jbe Exit
- jmp rw6
- ;
- ;
- ; Lines are off the top of the clip window
- ;
- ;
- ClippedTop:
- sub ebx,eax ; ebx=Lines to skip
- xor eax,eax
- sub ecx,ebx ; ecx=Lines in sprite
- jbe Exit ; Off top of screen
- rw8:
- mov al,[esi]
- add esi,2
- shr al,1
- ja rw8
- jnz rw8StringPacket ; Skip over lines in sprite data
- jc rw8
- dec esi
- dec ebx
- jnz rw8
- mov eax,paneY0 ; eax=top line
- jmp rw5
- rw8StringPacket:
- lea esi,[esi+eax-1]
- jmp rw8
- ;
- ;
- ; Sprite is clipped on either left or right
- ;
- ;
- ClippedLeft:
- sub edx,ecx
- mov edi,[edi+WINDOW.buffer] ; edi points to top left of buffer
- cmp ebx,edx
- jbe Exit ; Completly off left of screen?
- jmp ClippedX
- ClippedRight:
- cmp ecx,edx ; Completly off right of screen?
- jbe Exit
- ClippedX:
- imul DestWidth
- add edi,eax
- mov eax,paneX0
- mov edx,paneX1
- add eax,edi
- add edx,edi ; eax=Last pixel on right edge of clip window
- mov StartofClip,eax
- mov EndofClip,edx
- add edi,ecx
- xor ecx,ecx
- mov StartofLine,edi
- ;
- ; Clipped left and/or right drawing loop
- ;
- clineLoop:
- mov al,[esi]
- inc esi
- shr al,1
- ja cRunPacket
- jnz cStringPacket
- jnc cEndPacket
- //cSkipPacket:
- xor ecx,ecx
- mov al,[esi]
- inc esi
- xor cl,cl
- crp1a:
- cmp edi,StartofClip
- jc crp2a
- cmp edi,EndofClip
- jnbe clineLoop
- mov [edi],cl
- crp2a:
- inc edi
- dec al
- jnz crp1a
- jmp clineLoop
- cRunPacket:
- mov cl,[esi]
- inc esi
- crp1:
- cmp edi,StartofClip
- jc crp2
- cmp edi,EndofClip
- jnbe clineLoop
- mov [edi],cl
- crp2:
- inc edi
- dec al
- jnz crp1
- jmp clineLoop
- cStringPacket:
- mov cl,[esi]
- inc esi
- cmp edi,StartofClip
- jc crp3
- cmp edi,EndofClip
- jnbe crp3a
- mov [edi],cl
- crp3:
- inc edi
- dec al
- jnz cStringPacket
- jmp clineLoop
- crp3a:
- and eax,255
- lea esi,[esi+eax-1]
- jmp clineLoop
- cEndPacket:
- mov edx,DestWidth
- mov eax,EndofClip
- add eax,edx
- mov edi,StartofLine
- mov EndofClip,eax
- nop
- mov eax,StartofClip
- add edi,edx
- add eax,edx
- mov edx,lines
- mov StartofLine,edi
- dec edx
- mov StartofClip,eax
- mov lines,edx
- jnz clineLoop
- Exit:
- }
- }
- /*
- ;----------------------------------------------------------------------------
- ;
- ; int cdecl VFX_shape_translate_draw (PANE *panep, void *shape_table,
- ; long shape_number,int hotX, int hotY)
- ;
- ; This function clips and draws a shape to a pane. It is identical to
- ; VFX_shape_draw(), except that each pixel written is translated through a
- ; 256-byte table which was specified by a prior call to VFX_shape_lookaside().
- ;
- ; The panep parameter specifies the pane.
- ;
- ; The shape parameter specifies the shape, which must be in VFX Shape format.
- ;
- ; The hotX and hotY parameters specify the location where the shape is to be
- ; drawn. The shape's hot spot will end up at the specified location.
- ;
- ; For more information, see the "VFX Shape Format Description".
- ;
- ; Return values:
- ;
- ; 0: OK
- ; -1: Bad window
- ; -2: Bad pane
- ; -3: Shape off pane
- ; -4: Null shape
- ;
- ;----------------------------------------------------------------------------
- */
- void AG_shape_translate_fill (PANE *pane, void *shape_table,LONG shape_number, LONG hotX, LONG hotY)
- {
- _asm{
- mov edi,pane
- nop
- ;
- ; Clip left and right of clipping window
- ;
- mov ecx,[edi+PANE.x0]
- mov edx,[edi+PANE.y0]
- mov ebx,ecx
- mov eax,edx
- sar ebx,31
- xor eax,-1
- sar eax,31 ; If less than 0, make 0
- xor ebx,-1
- and ecx,ebx
- and edx,eax
- mov paneX0,ecx
- mov paneY0,edx
- ;
- ; Clip top and bottom of clipping window
- ;
- mov ecx,[edi+PANE.x1]
- mov edx,[edi+PANE.y1]
- mov edi,[edi+PANE.window]
- mov esi,shape_table
- mov eax,[edi+WINDOW.x_max]
- xor ebx,ebx
- inc eax
- nop
- sub ecx,eax
- mov DestWidth,eax
- setge bl
- dec ebx ; if ecx is less than eax, load ecx with eax
- nop
- and ecx,ebx
- mov ebx,[edi+WINDOW.y_max]
- add ecx,eax
- inc ebx
- xor eax,eax
- sub edx,ebx
- setge al
- dec eax
- mov paneX1,ecx
-
- and edx,eax
- mov eax,shape_number
- add edx,ebx
- mov ebx,paneY0
- ;
- ; paneX0,Y0 to PaneX1,Y1 are 0,0 -> 639,479 or window size to render too
- ;
- mov ecx,[esi+eax*8+8] ; ESI now points to start of sprite data
- mov paneY1,edx
- lea esi,[esi+ecx+SIZE SHAPEHEADER]
- mov edx,hotY
- mov ecx,[esi+SHAPEHEADER.xmax-SIZE SHAPEHEADER]
- mov eax,[esi+SHAPEHEADER.xmin-SIZE SHAPEHEADER]
- mov tempXmax,ecx ; Store Xmax and Xmin
- mov tempXmin,eax
- mov ecx,[esi+SHAPEHEADER.ymax-SIZE SHAPEHEADER]
- mov eax,[esi+SHAPEHEADER.ymin-SIZE SHAPEHEADER]
- sub ecx,eax ; ecx = Height of sprite
- add eax,edx ; eax = top line
- inc ecx ; Add one line
- nop
- ;
- ; Now check for lines off the top of the clipping window
- ;
- cmp eax,ebx
- jl ClippedTop
- ;
- ; Now check for lines off the bottom of the clipping window
- ;
- rw5:
- lea ebx,[eax+ecx-1] ; ebx=Last Line
- nop
- sub ebx,paneY1 ; Check to see if off bottom
- ja ClippedBottom
- rw6:
- mov lines,ecx ; eax still equals top line
- ;
- ; Now check clipping in X
- ;
- mov ebx,tempXmax
- mov ecx,tempXmin
- mov edx,paneX0
- sub ebx,ecx ; ebx = Width of sprite
- add ecx,hotX ; ecx = offset to left edge
- cmp ecx,edx ; Is sprite off left edge of screen?
- jl ClippedLeft
- lea edx,[ebx+ecx-1]
- mov edi,[edi+WINDOW.buffer] ; edi points to top left of buffer
- sub edx,paneX1
- jnc ClippedRight
- ;
- ; Work out screen position
- ;
- //NowDraw:
- imul DestWidth
- add eax,ecx
- xor ecx,ecx
- add edi,eax
- mov StartofLine,edi
- push ebp
- mov ebp,lookaside
- xor ebx,ebx
- nop
- ;
- ; Main drawing loop
- ;
- ;
- lineLoop:
- mov al,[esi]
- inc esi
- shr al,1
- ja RunPacket
- jnz StringPacket
- jnc EndPacket
- //SkipPacket:
- xor ecx,ecx
- mov al,[esi]
- inc esi
- xor cl,cl
- rp1a:
- mov [edi],cl
- inc edi
- dec al
- jnz rp1a
- jmp lineLoop
- RunPacket:
- xor ecx,ecx
- mov cl,[esi]
- inc esi
- mov cl,[ecx+ebp]
- rp1:
- mov [edi],cl
- inc edi
- dec al
- jnz rp1
- jmp lineLoop
- StringPacket:
- //
- // 17 cycles / 8 bytes - 2.125 per byte
- //
- sub al,8
- jc sp2
- sp1:
- mov cl,[esi]
- mov bl,[esi+4]
- mov cl,[ecx+ebp]
- mov bl,[ebx+ebp]
- mov [edi],cl
- mov [edi+4],bl
- mov cl,[esi+1]
- mov bl,[esi+5]
- mov cl,[ecx+ebp]
- mov bl,[ebx+ebp]
- mov [edi+1],cl
- mov [edi+5],bl
- mov cl,[esi+2]
- mov bl,[esi+6]
- mov cl,[ecx+ebp]
- mov bl,[ebx+ebp]
- mov [edi+2],cl
- mov [edi+6],bl
- mov cl,[esi+3]
- mov bl,[esi+7]
- add esi,8
- add edi,8
- mov cl,[ecx+ebp]
- mov bl,[ebx+ebp]
- mov [edi+3-8],cl
- mov [edi+7-8],bl
- sub al,8
- jnc sp1
- sp2:
- add al,8
- jz lineLoop
- sp3:
- xor ecx,ecx
- mov cl,[esi]
- mov cl,[ecx+ebp]
- inc esi
- mov [edi],cl
- inc edi
- dec al
- jnz sp3
- jmp lineLoop
- EndPacket:
- mov edx,DestWidth
- mov edi,StartofLine
- add edi,edx
- mov edx,lines
- dec edx
- mov StartofLine,edi
- mov lines,edx
- jnz lineLoop
- pop ebp
- jmp Exit
- ;
- ;
- ; Lines are clipped off the bottom of the clip window
- ;
- ;
- ClippedBottom:
- sub ecx,ebx ; Remove lines that go off bottom
- jbe Exit
- jmp rw6
- ;
- ;
- ; Lines are off the top of the clip window
- ;
- ;
- ClippedTop:
- sub ebx,eax ; ebx=Lines to skip
- xor eax,eax
- sub ecx,ebx ; ecx=Lines in sprite
- jbe Exit ; Off top of screen
- rw8:
- mov al,[esi]
- add esi,2
- shr al,1
- ja rw8
- jnz rw8StringPacket ; Skip over lines in sprite data
- jc rw8
- dec esi
- dec ebx
- jnz rw8
- mov eax,paneY0 ; eax=top line
- jmp rw5
- rw8StringPacket:
- lea esi,[esi+eax-1]
- jmp rw8
- ;
- ;
- ; Sprite is clipped on either left or right
- ;
- ;
- ClippedLeft:
- sub edx,ecx
- mov edi,[edi+WINDOW.buffer] ; edi points to top left of buffer
- cmp ebx,edx
- jbe Exit ; Completly off left of screen?
- jmp ClippedX
- ClippedRight:
- cmp ecx,edx ; Completly off right of screen?
- jbe Exit
- ClippedX:
- imul DestWidth
- add edi,eax
- mov eax,paneX0
- mov edx,paneX1
- add eax,edi
- add edx,edi ; eax=Last pixel on right edge of clip window
- mov StartofClip,eax
- mov EndofClip,edx
- add edi,ecx
- xor ecx,ecx
- mov StartofLine,edi
- push ebp
- mov ebp,lookaside
- ;
- ; Clipped left and/or right drawing loop
- ;
- clineLoop:
- mov al,[esi]
- inc esi
- shr al,1
- ja cRunPacket
- jnz cStringPacket
- jnc cEndPacket
- //cSkipPacket:
- mov al,[esi]
- inc esi
- xor cl,cl
- crp1a:
- cmp edi,StartofClip
- jc crp2a
- cmp edi,EndofClip
- jnc clineLoop
- mov [edi],cl
- crp2a:
- inc edi
- dec al
- jnz crp1a
- jmp clineLoop
- cRunPacket:
- mov cl,[esi]
- inc esi
- crp1:
- cmp edi,StartofClip
- jc crp2
- cmp edi,EndofClip
- jnc clineLoop
- mov cl,[ecx+ebp]
- mov [edi],cl
- crp2:
- inc edi
- dec al
- jnz crp1
- jmp clineLoop
- cStringPacket:
- mov cl,[esi]
- inc esi
- cmp edi,StartofClip
- jc crp3
- cmp edi,EndofClip
- jnc crp3a
- mov cl,[ecx+ebp]
- mov [edi],cl
- crp3:
- inc edi
- dec al
- jnz cStringPacket
- jmp clineLoop
- crp3a:
- and eax,255
- lea esi,[esi+eax-1]
- jmp clineLoop
- cEndPacket:
- mov edx,DestWidth
- mov eax,EndofClip
- add eax,edx
- mov edi,StartofLine
- mov EndofClip,eax
- nop
- mov eax,StartofClip
- add edi,edx
- add eax,edx
- mov edx,lines
- mov StartofLine,edi
- dec edx
- mov StartofClip,eax
- mov lines,edx
- jnz clineLoop
- pop ebp
- Exit:
- }
- }
|