📄 nescom.h
字号:
/* Copyright 2001, ESS Technology, Inc./* SCCSID @(#)nescom.h 1.14 05/19/03 *//* * $Log$ *//** iNES: portable NES emulator ******************************//** **//** Common.h **//** **//** This file contains screen refresh drivers which are **//** common for both X11 and VGA implementations. It is **//** included either from Unix.c or MSDOS.c. **//** **//** Copyright (C) Marat Fayzullin 1994-2000 **//** The contents of this file are property of Marat **//** Fayzullin and should only be used as agreed with **//** him. The file is confidential. Absolutely no **//** distribution allowed. **//*************************************************************/#ifdef INESinline int NES_RefreshSprites(/*int Y*/byte *P,byte *Z);#define NES_BLACK 63/** RefreshLine() ********************************************//** Refresh a single scanline on screen, and draw sprites **//** in it. Returns 1 if intersection of sprite #0 with the **//** background occurs, 0 otherwise. **//*************************************************************/inline int NES_RefreshLine(register int DY,register int SY){ register byte/* X1,X2,Shift,*/*R,*Z; register pixel *P,*C, *PP; register int D0,D1, X1, X2, Shift, Scr; byte *ChrTab,*CT,*AT, *XPal; pixel Pal[16]; byte ZBuf[35]; if(DY<8 || DY>=232) return 0; P=(pixel *)XBuf+8+NES_WIDTH*DY; PP = P; /* If display is off... */ if(!SCREENON) { /* Clear scanline and Z-buffer */ ZBuf[32]=ZBuf[33]=ZBuf[34]=0; for(D0=0;D0<32;D0++,P+=8) { P[0]=P[1]=P[2]=P[3]=P[4]=P[5]=P[6]=P[7]=NES_BLACK; ZBuf[D0]=0; } /* Refresh sprites in this scanline */ D0=ines->FirstSprite>=0? NES_RefreshSprites(/*DY*/PP,ZBuf+1):0; /* Return hit flag */ return(D0); } /* Get colors into array for fast lookup */ XPal = ines->XPal; for(X1=0;X1<16;) { Pal[X1]=XPal[NES_ChrCol[0]&0x3F];X1++; Pal[X1]=XPal[NES_ChrCol[X1]&0x3F];X1++; Pal[X1]=XPal[NES_ChrCol[X1]&0x3F];X1++; Pal[X1]=XPal[NES_ChrCol[X1]&0x3F];X1++; } Scr=((SY&0x100)>>7)+((NSCROLLX&0x100)>>8); SY&=0xFF; ChrTab=ines->VPage[Scr+8]; CT=ChrTab+((SY&0xF8)<<2); AT=ChrTab+0x03C0+((SY&0xE0)>>2); X1=(NSCROLLX&0xF8)>>3; Shift=NSCROLLX&0x07; P-=Shift; Z=ZBuf; Z[0]=0x00; for(X2=0;X2<33;X2++) { /* Fetch data */ C=Pal+((( AT[X1>>2] >> ((X1&0x02)+((SY&0x10)>>2)) )&0x03)<<2); R=NES_ChrGen+((int)(CT[X1])<<4)+(SY&0x07); D0=*R; /* Modify Z-buffer */ D1=(D0|*(R+8))<<Shift; Z[0]|=D1>>8; Z[1]=D1&0xFF; Z++; /* Draw pixels */ D1=(int)*(R+8)<<1; D1=(D1&0xAAA)|((D1&0x555)<<7)|(D0&0x55)|((D0&0xAA)<<7); P[0]=C[D1>>14]; P[1]=C[(D1&0x00C0)>>6]; P[2]=C[(D1&0x3000)>>12]; P[3]=C[(D1&0x0030)>>4]; P[4]=C[(D1&0x0C00)>>10]; P[5]=C[(D1&0x000C)>>2]; P[6]=C[(D1&0x0300)>>8]; P[7]=C[D1&0x0003]; P+=8; X1=(X1+1)&0x1F; if(!X1) { D1=CT-ChrTab; ChrTab=ines->VPage[(Scr^0x01)+8]; CT=ChrTab+D1; AT=ChrTab+0x03C0+((SY&0xE0)>>2); } } /* Refresh sprites in this scanline */ D0=ines->FirstSprite>=0? NES_RefreshSprites(/*DY*/PP,ZBuf+1):0; /* Mask out left 8 pixels if needed */ if(!LEFTIMG) { P+=Shift-8-256; P[0]=P[1]=P[2]=P[3]=P[4]=P[5]=P[6]=P[7]=NES_BLACK; } /* Return 1 if we hit sprite #0 */ return(D0);}/** RefreshSprites *******************************************//** Refresh sprites at a given scanline. Returns 1 if **//** intersection of sprite #0 with the background occurs, 0 **//** otherwise. **//*************************************************************/inline int NES_RefreshSprites(/*register int Y*/byte *PP,register byte *Z){ register byte *T, *XPal, *SprCol; register pixel *P,*C; register int D0,D1,J,I; pixel *Pal; Pal = ines->SprPal; XPal = ines->XPal; for(J=0;J<16;) { Pal[J]=XPal[NES_SprCol[0]&0x3F];J++; Pal[J]=XPal[NES_SprCol[J]&0x3F];J++; Pal[J]=XPal[NES_SprCol[J]&0x3F];J++; Pal[J]=XPal[NES_SprCol[J]&0x3F];J++; } for(J=ines->FirstSprite,T=P_SRAM+(J<<2),I=0;J>=0;J--,T-=4) if(D1=Sprites[J]) { /* Compute background mask if needed */ if(S_BEHIND(T)||!J) { D0=T[3]; I=8-(D0&0x07); D0>>=3; D0=((((int)Z[D0]<<8)|Z[D0+1])>>I)&0xFF; D0=(D0&0x55)|((D0&0xAA)<<7); D0=D0|(D0<<1); /* Compute hit flag if needed */ I=J? 0:((D0&D1)!=0); /* Mask bits if needed */ if(S_BEHIND(T)) D1&=~D0; } /* If any bits left to draw... */ if(D1) { P=/*(pixel *)XBuf+8+NES_WIDTH*Y*/PP+T[3]; C=Pal+(S_COLOR(T)<<2); if(D0=D1&0xC000) P[0]=C[D0>>14]; if(D0=D1&0x00C0) P[1]=C[D0>>6]; if(D0=D1&0x3000) P[2]=C[D0>>12]; if(D0=D1&0x0030) P[3]=C[D0>>4]; if(D0=D1&0x0C00) P[4]=C[D0>>10]; if(D0=D1&0x000C) P[5]=C[D0>>2]; if(D0=D1&0x0300) P[6]=C[D0>>8]; if(D0=D1&0x0003) P[7]=C[D0]; } } /* If I contains nonzero value at this point, */ /* then we have hit sprite #0 */ return(I);}#endif /* INES */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -