1 /* FCE Ultra - NES/Famicom Emulator
3 * Copyright notice for this file:
4 * Copyright (C) 1998 BERO
5 * Copyright (C) 2002 Ben Parnell
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 extern INPUTC *FCEU_InitZapper(int w);
33 extern INPUTC *FCEU_InitPowerpad(int w);
34 extern INPUTC *FCEU_InitArkanoid(int w);
36 extern INPUTCFC *FCEU_InitArkanoidFC(void);
37 extern INPUTCFC *FCEU_InitSpaceShadow(void);
38 extern INPUTCFC *FCEU_InitFKB(void);
39 static uint8 joy_readbit[2];
40 static uint16 joy[2]={0,0};
44 static int FSDisable=0; /* Set to 1 if NES-style four-player adapter is disabled. */
45 static int JPAttrib[2]={0,0};
46 static int JPType[2]={0,0};
47 static void *InputDataPtr[2];
49 static int JPAttribFC=0;
50 static int JPTypeFC=0;
51 static void *InputDataPtrFC;
53 void (*InputScanlineHook)(uint8 *buf, int line);
55 static INPUTC DummyJPort={0,0,0,0,0};
56 static INPUTC *JPorts[2]={&DummyJPort,&DummyJPort};
57 static INPUTCFC *FCExp=0;
59 static uint8 FP_FASTAPASS(1) ReadGPVS(int w)
67 ret = ((joy[w]>>(joy_readbit[w]))&1);
73 static uint8 FP_FASTAPASS(1) ReadGP(int w)
78 //ret = ((joy[w]>>(joy_readbit[w]))&1)|
79 //(((joy[w]>>(joy_readbit[w]+8))&1)<<1);
80 //if(joy_readbit[w]>8) ret=0;
82 ret = ((joy[w]>>(joy_readbit[w]))&1);
85 if(joy_readbit[w]>=8) ret|=1;
89 if(joy_readbit[w]==19-w) ret|=1;
100 ret|=JPorts[A&1]->Read(A&1);
104 ret=FCExp->Read(A&1,ret);
117 JPorts[0]->Write(V&1);
119 JPorts[1]->Write(V&1);
121 if((PSG[0x16]&1) && (!(V&1)))
123 /* This strobe code is just for convenience. If it were
124 with the code in input / *.c, it would more accurately represent
125 what's really going on. But who wants accuracy? ;)
126 Seriously, though, this shouldn't be a problem.
128 if(JPorts[0]->Strobe)
129 JPorts[0]->Strobe(0);
130 if(JPorts[1]->Strobe)
131 JPorts[1]->Strobe(1);
139 static void FP_FASTAPASS(1) StrobeGP(int w)
144 static INPUTC GPC={ReadGP,0,StrobeGP,0,0,0};
145 static INPUTC GPCVS={ReadGPVS,0,StrobeGP,0,0,0};
147 void DrawInput(uint8 *buf)
153 JPorts[x]->Draw(x,buf,JPAttrib[x]);
156 FCExp->Draw(buf,JPAttribFC);
159 void UpdateInput(void)
168 if(!x) joy[0]=*(uint16 *)InputDataPtr[0];
169 else joy[1]=*(uint16 *)InputDataPtr[1];
172 if(JPorts[x]->Update)
173 JPorts[x]->Update(x,InputDataPtr[x],JPAttrib[x]);
179 FCExp->Update(InputDataPtrFC,JPAttribFC);
181 if(FCEUGameInfo.type==GIT_VSUNI)
184 joy[0]=(joy[0]&0xC)|(joy[1]&0xF3);
185 joy[1]=(joy[1]&0xC)|(t&0xF3);
189 if(netplay) NetplayUpdate(&joy[0],&joy[1]);
194 static DECLFR(VSUNIRead0)
199 ret|=(JPorts[0]->Read(0))&1;
207 static DECLFR(VSUNIRead1)
212 ret|=(JPorts[1]->Read(1))&1;
217 static void SLHLHook(uint8 *buf, int line)
222 if(JPorts[x]->SLHook)
223 JPorts[x]->SLHook(x,buf,line);
226 FCExp->SLHook(buf,line);
229 static void CheckSLHook(void)
232 if(JPorts[0]->SLHook || JPorts[1]->SLHook)
233 InputScanlineHook=SLHLHook;
236 InputScanlineHook=SLHLHook;
239 static void FASTAPASS(1) SetInputStuff(int x)
244 if(FCEUGameInfo.type==GIT_VSUNI)
249 case SI_ARKANOID:JPorts[x]=FCEU_InitArkanoid(x);break;
250 case SI_ZAPPER:JPorts[x]=FCEU_InitZapper(x);break;
251 case SI_POWERPAD:JPorts[x]=FCEU_InitPowerpad(x);break;
252 case SI_NONE:JPorts[x]=&DummyJPort;break;
258 static uint8 F4ReadBit[2];
259 static void StrobeFami4(void)
261 F4ReadBit[0]=F4ReadBit[1]=0;
264 static uint8 FP_FASTAPASS(2) ReadFami4(int w, uint8 ret)
268 ret |= ((joy[w]>>(F4ReadBit[w]+8))&1)<<1;
269 if(F4ReadBit[w]>=8) ret|=2;
275 static INPUTCFC FAMI4C={ReadFami4,0,StrobeFami4,0,0,0};
276 static void SetInputStuffFC(void)
280 case SIFC_NONE:FCExp=0;break;
281 case SIFC_ARKANOID:FCExp=FCEU_InitArkanoidFC();break;
282 case SIFC_SHADOW:FCExp=FCEU_InitSpaceShadow();break;
283 case SIFC_4PLAYER:FCExp=&FAMI4C;memset(&F4ReadBit,0,sizeof(F4ReadBit));break;
284 case SIFC_FKB:FCExp=FCEU_InitFKB();break;
289 // VS Unisystem code called after SetInputMap() hooks B4016. Need to
290 // rewrite code to make this more sane?
292 void InitializeInput(void)
294 memset(joy_readbit,0,sizeof(joy_readbit));
295 memset(joy,0,sizeof(joy));
297 if(FCEUGameInfo.type==GIT_VSUNI)
299 SetReadHandler(0x4016,0x4016,VSUNIRead0);
300 SetReadHandler(0x4017,0x4017,VSUNIRead1);
303 SetReadHandler(0x4016,0x4017,JPRead);
304 SetWriteHandler(0x4016,0x4016,B4016);
311 void FCEUI_SetInput(int port, int type, void *ptr, int attrib)
313 JPAttrib[port]=attrib;
315 InputDataPtr[port]=ptr;
319 void FCEUI_DisableFourScore(int s)
324 void FCEUI_SetInputFC(int type, void *ptr, int attrib)