098 renderer added
[fceu.git] / input / shadow.c
1 /* FCE Ultra - NES/Famicom Emulator
2  *
3  * Copyright notice for this file:
4  *  Copyright (C) 2002 Xodnizel
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include        <string.h>
22 #include        <stdlib.h>
23
24 #include        "share.h"
25
26 typedef struct {
27         uint32 mzx,mzy,mzb;
28         int zap_readbit;
29         int bogo;
30         int zappo;
31         uint64 zaphit;
32 } ZAPPER;
33
34 static ZAPPER ZD;
35
36 static void FP_FASTAPASS(3) ZapperFrapper(uint8 *bg, uint8 *spr, uint32  linets, int final)
37 {
38  int xs,xe;
39  int zx,zy;
40
41  if(!bg) // New line, so reset stuff.
42  {
43   ZD.zappo=0;
44   return;
45  }
46  xs=ZD.zappo;
47  xe=final;
48
49  zx=ZD.mzx;
50  zy=ZD.mzy;
51
52  if(xe>256) xe=256;
53
54  if(scanline>=(zy-4) && scanline<=(zy+4))
55  {
56   while(xs<xe)
57   {
58     uint8 a1,a2;
59     uint32 sum;
60     if(xs<=(zx+4) && xs>=(zx-4))
61     {
62      a1=bg[xs];
63      if(spr)
64      {
65       a2=spr[xs];
66
67       if(!(a2&0x80))
68        if(!(a2&0x40) || (a1&64))
69         a1=a2;
70      }
71      a1&=63;
72
73      sum=palo[a1].r+palo[a1].g+palo[a1].b;
74      if(sum>=100*3)
75      {
76       ZD.zaphit=((uint64)linets+(xs+16)*(PAL?15:16))/48+timestampbase;
77       goto endo;
78      }
79     }
80    xs++;
81   }
82  }
83  endo:
84  ZD.zappo=final;
85 }
86
87 static INLINE int CheckColor(void)
88 {
89  FCEUPPU_LineUpdate();
90
91  if((ZD.zaphit+10)>=(timestampbase+timestamp)) return(0);
92
93  return(1);
94 }
95
96
97 static uint8 FP_FASTAPASS(2) ReadZapper(int w, uint8 ret)
98 {
99                 if(w)
100                 {
101                  ret&=~0x18;
102                  if(ZD.bogo)
103                   ret|=0x10;
104                  if(CheckColor())
105                   ret|=0x8;
106                 }
107                 else
108                 {
109                  //printf("Kayo: %d\n",ZD.zap_readbit);
110                  ret&=~2;
111                  //if(ZD.zap_readbit==4) ret|=ZD.mzb&2;
112                  ret|=(ret&1)<<1;
113                  //ZD.zap_readbit++;
114                 }
115                 return ret;
116 }
117
118 static void FP_FASTAPASS(2) DrawZapper(uint8 *buf, int arg)
119 {
120  if(arg)
121   FCEU_DrawCursor(buf, ZD.mzx, ZD.mzy);
122 }
123
124 static void FP_FASTAPASS(2) UpdateZapper(void *data, int arg)
125 {
126   uint32 *ptr=(uint32*)data;
127
128   if(ZD.bogo)
129    ZD.bogo--;
130   if(ptr[2]&1 && (!(ZD.mzb&1)))
131    ZD.bogo=5;
132
133   ZD.mzx=ptr[0];
134   ZD.mzy=ptr[1];
135   ZD.mzb=ptr[2];
136 }
137
138 static void StrobeShadow(void)
139 {
140  ZD.zap_readbit=0;
141 }
142
143 static INPUTCFC SHADOWC={ReadZapper,0,StrobeShadow,UpdateZapper,ZapperFrapper,DrawZapper};
144
145 INPUTCFC *FCEU_InitSpaceShadow(void)
146 {
147   memset(&ZD,0,sizeof(ZAPPER));
148   return(&SHADOWC);
149 }
150
151