098 renderer added
[fceu.git] / input / zapper.c
CommitLineData
c62d2810 1/* FCE Ultra - NES/Famicom Emulator
2 *
3 * Copyright notice for this file:
e328100e 4 * Copyright (C) 2002 Xodnizel
c62d2810 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>
e328100e 22#include <stdlib.h>
c62d2810 23
24#include "share.h"
25
26typedef struct {
27 uint32 mzx,mzy,mzb;
28 int zap_readbit;
29 int bogo;
e328100e 30 int zappo;
31 uint64 zaphit;
c62d2810 32} ZAPPER;
33
34static ZAPPER ZD[2];
35
e328100e 36static void FP_FASTAPASS(3) ZapperFrapper(int w, uint8 *bg, uint8 *spr, uint32 linets, int final)
c62d2810 37{
e328100e 38 int xs,xe;
39 int zx,zy;
40
41 if(!bg) // New line, so reset stuff.
42 {
43 ZD[w].zappo=0;
44 return;
45 }
46 xs=ZD[w].zappo;
47 xe=final;
48
49 zx=ZD[w].mzx;
50 zy=ZD[w].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[w].zaphit=((uint64)linets+(xs+16)*(PAL?15:16))/48+timestampbase;
77 goto endo;
78 }
79 }
80 xs++;
81 }
82 }
83 endo:
84 ZD[w].zappo=final;
c62d2810 85}
86
87static INLINE int CheckColor(int w)
88{
6244011f 89 FCEUPPU_LineUpdate();
e328100e 90
91 if((ZD[w].zaphit+100)>=(timestampbase+timestamp)
92 && !(ZD[w].mzb&2)) return(0);
93
94 return(1);
c62d2810 95}
96
97static uint8 FP_FASTAPASS(1) ReadZapperVS(int w)
98{
99 uint8 ret=0;
100
101 if(ZD[w].zap_readbit==4) ret=1;
102
103 if(ZD[w].zap_readbit==7)
104 {
105 if(ZD[w].bogo)
106 ret|=0x1;
107 }
108 if(ZD[w].zap_readbit==6)
109 {
110 if(!CheckColor(w))
111 ret|=0x1;
112 }
e328100e 113 if(!fceuindbg)
114 ZD[w].zap_readbit++;
c62d2810 115 return ret;
116}
117
118static void FP_FASTAPASS(1) StrobeZapperVS(int w)
e328100e 119{
c62d2810 120 ZD[w].zap_readbit=0;
121}
122
123static uint8 FP_FASTAPASS(1) ReadZapper(int w)
124{
125 uint8 ret=0;
126 if(ZD[w].bogo)
127 ret|=0x10;
128 if(CheckColor(w))
129 ret|=0x8;
130 return ret;
131}
132
133static void FASTAPASS(3) DrawZapper(int w, uint8 *buf, int arg)
134{
135 if(arg)
e328100e 136 FCEU_DrawGunSight(buf, ZD[w].mzx,ZD[w].mzy);
c62d2810 137}
138
139static void FP_FASTAPASS(3) UpdateZapper(int w, void *data, int arg)
140{
e328100e 141 uint32 *ptr=(uint32 *)data;
c62d2810 142
e328100e 143 //FCEU_DispMessage("%3d:%3d",ZD[w].mzx,ZD[w].mzy);
c62d2810 144 if(ZD[w].bogo)
145 ZD[w].bogo--;
146 if(ptr[2]&3 && (!(ZD[w].mzb&3)))
147 ZD[w].bogo=5;
148
149 ZD[w].mzx=ptr[0];
150 ZD[w].mzy=ptr[1];
151 ZD[w].mzb=ptr[2];
c62d2810 152}
153
e328100e 154static INPUTC ZAPC={ReadZapper,0,0,UpdateZapper,ZapperFrapper,DrawZapper};
155static INPUTC ZAPVSC={ReadZapperVS,0,StrobeZapperVS,UpdateZapper,ZapperFrapper,DrawZapper};
c62d2810 156
157INPUTC *FCEU_InitZapper(int w)
158{
159 memset(&ZD[w],0,sizeof(ZAPPER));
e328100e 160 if(FCEUGameInfo.type == GIT_VSUNI)
c62d2810 161 return(&ZAPVSC);
162 else
163 return(&ZAPC);
164}
165
166