initial fce ultra 0.81 import
[fceu.git] / input / shadow.c
1 /* FCE Ultra - NES/Famicom Emulator
2  *
3  * Copyright notice for this file:
4  *  Copyright (C) 2002 Ben Parnell
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         uint32 colok;
31         uint32 coloklast;
32 } ZAPPER;
33
34 static ZAPPER ZD;
35
36 static void FP_FASTAPASS(2) ZapperThingy(uint8 *buf, int line)
37 {
38         int mzx=ZD.mzx;
39
40         if(line==0) ZD.colok=1<<16;     /* Disable it. */
41         ZD.coloklast=ZD.colok;
42
43         if((line>=ZD.mzy-3 && line<=ZD.mzy+3) && mzx<256)
44         {
45          int a,sum,x;
46
47          for(x=-4;x<4;x++)
48          {
49           if((mzx+x)<0 || (mzx+x)>255) continue;
50           a=buf[mzx+x]&63;
51           sum=palo[a].r+palo[a].g+palo[a].b;
52          
53           if(sum>=100*3)
54           {
55            ZD.colok=timestamp+mzx/3;
56            break;
57           }
58          }
59         }
60 }
61
62 static INLINE int CheckColor(void)
63 {
64   if( (timestamp>=ZD.coloklast && timestamp<=(ZD.coloklast+10)) ||
65    (timestamp>=ZD.colok && timestamp<=(ZD.colok+10)) )
66    return 0;
67   return 1;
68 }
69
70 static uint8 FP_FASTAPASS(2) ReadZapper(int w, uint8 ret)
71 {
72                 if(w)
73                 {
74                  ret&=~0x18;
75                  if(ZD.bogo)
76                   ret|=0x10;
77                  if(CheckColor())
78                   ret|=0x8;
79                 }
80                 else
81                 {
82                  //printf("Kayo: %d\n",ZD.zap_readbit);
83                  ret&=~2;
84                  //if(ZD.zap_readbit==4) ret|=ZD.mzb&2;
85                  ret|=(ret&1)<<1;
86                  //ZD.zap_readbit++;
87                 }
88                 return ret;
89 }
90
91 static void FP_FASTAPASS(2) DrawZapper(uint8 *buf, int arg)
92 {
93  if(arg)
94   FCEU_DrawCursor(buf, ZD.mzx, ZD.mzy);
95 }
96
97 static void FP_FASTAPASS(2) UpdateZapper(void *data, int arg)
98 {
99   uint32 *ptr=data;
100
101   if(ZD.bogo)
102    ZD.bogo--;
103   if(ptr[2]&1 && (!(ZD.mzb&1)))
104    ZD.bogo=5;
105
106   ZD.mzx=ptr[0];
107   ZD.mzy=ptr[1];
108   ZD.mzb=ptr[2];
109
110   if(ZD.mzx>=256 || ZD.mzy>=240)
111    ZD.colok=0;
112 }
113
114 static void StrobeShadow(void)
115 {
116  ZD.zap_readbit=0;
117 }
118
119 static INPUTCFC SHADOWC={ReadZapper,0,StrobeShadow,UpdateZapper,ZapperThingy,DrawZapper};
120
121 INPUTCFC *FCEU_InitSpaceShadow(void)
122 {
123   memset(&ZD,0,sizeof(ZAPPER));
124   return(&SHADOWC);
125 }
126
127