/* FCE Ultra - NES/Famicom Emulator * * Copyright notice for this file: * Copyright (C) 2002 Xodnizel * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "share.h" typedef struct { uint32 mzx,mzy,mzb; int zap_readbit; int bogo; int zappo; uint64 zaphit; } ZAPPER; static ZAPPER ZD; static void ZapperFrapper(uint8 *bg, uint8 *spr, uint32 linets, int final) { int xs,xe; int zx,zy; if(!bg) // New line, so reset stuff. { ZD.zappo=0; return; } xs=ZD.zappo; xe=final; zx=ZD.mzx; zy=ZD.mzy; if(xe>256) xe=256; if(scanline>=(zy-4) && scanline<=(zy+4)) { while(xs=(zx-4)) { a1=bg[xs]; if(spr) { a2=spr[xs]; if(!(a2&0x80)) if(!(a2&0x40) || (a1&64)) a1=a2; } a1&=63; sum=palo[a1].r+palo[a1].g+palo[a1].b; if(sum>=100*3) { ZD.zaphit=((uint64)linets+(xs+16)*(PAL?15:16))/48+timestampbase; goto endo; } } xs++; } } endo: ZD.zappo=final; } static INLINE int CheckColor(void) { FCEUPPU_LineUpdate(); if((ZD.zaphit+10)>=(timestampbase+timestamp)) return(0); return(1); } static uint8 ReadZapper(int w, uint8 ret) { if(w) { ret&=~0x18; if(ZD.bogo) ret|=0x10; if(CheckColor()) ret|=0x8; } else { //printf("Kayo: %d\n",ZD.zap_readbit); ret&=~2; //if(ZD.zap_readbit==4) ret|=ZD.mzb&2; ret|=(ret&1)<<1; //ZD.zap_readbit++; } return ret; } static void DrawZapper(uint8 *buf, int arg) { FCEU_DrawCursor(buf, ZD.mzx, ZD.mzy); } static void UpdateZapper(void *data, int arg) { uint32 *ptr=(uint32*)data; if(ZD.bogo) ZD.bogo--; if(ptr[2]&1 && (!(ZD.mzb&1))) ZD.bogo=5; ZD.mzx=ptr[0]; ZD.mzy=ptr[1]; ZD.mzb=ptr[2]; } static void StrobeShadow(void) { ZD.zap_readbit=0; } static INPUTCFC SHADOWC={ReadZapper,0,StrobeShadow,UpdateZapper,ZapperFrapper,DrawZapper}; INPUTCFC *FCEU_InitSpaceShadow(void) { memset(&ZD,0,sizeof(ZAPPER)); return(&SHADOWC); }