nesinput.c
  1  /*
  2  ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com)
  3  **
  4  **
  5  ** This program is free software; you can redistribute it and/or
  6  ** modify it under the terms of version 2 of the GNU Library General 
  7  ** Public License as published by the Free Software Foundation.
  8  **
  9  ** This program is distributed in the hope that it will be useful, 
 10  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 12  ** Library General Public License for more details.  To obtain a 
 13  ** copy of the GNU Library General Public License, write to the Free 
 14  ** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 15  **
 16  ** Any permitted reproduction of these routines, in whole or in part,
 17  ** must bear this legend.
 18  **
 19  **
 20  ** nesinput.c
 21  **
 22  ** Event handling system routines
 23  ** $Id: nesinput.c,v 1.2 2001/04/27 14:37:11 neil Exp $
 24  */
 25  
 26  #include "noftypes.h"
 27  #include "nesinput.h"
 28  #include "log.h"
 29  
 30  /* TODO: make a linked list of inputs sources, so they
 31  **       can be removed if need be
 32  */
 33  
 34  static nesinput_t *nes_input[MAX_CONTROLLERS];
 35  static int active_entries = 0;
 36  
 37  /* read counters */
 38  static int pad0_readcount, pad1_readcount, ppad_readcount, ark_readcount;
 39  
 40  
 41  static int retrieve_type(int type)
 42  {
 43     int i, value = 0;
 44  
 45     for (i = 0; i < active_entries; i++)
 46     {
 47        ASSERT(nes_input[i]);
 48  
 49        if (type == nes_input[i]->type)
 50           value |= nes_input[i]->data;
 51     }
 52  
 53     return value;
 54  }
 55  
 56  static uint8 get_pad0(void)
 57  {
 58     uint8 value;
 59  
 60     value = (uint8) retrieve_type(INP_JOYPAD0);
 61  
 62     /* mask out left/right simultaneous keypresses */
 63     if ((value & INP_PAD_UP) && (value & INP_PAD_DOWN))
 64        value &= ~(INP_PAD_UP | INP_PAD_DOWN);
 65  
 66     if ((value & INP_PAD_LEFT) && (value & INP_PAD_RIGHT))
 67        value &= ~(INP_PAD_LEFT | INP_PAD_RIGHT);
 68  
 69     /* return (0x40 | value) due to bus conflicts */
 70     return (0x40 | ((value >> pad0_readcount++) & 1));
 71  }
 72  
 73  static uint8 get_pad1(void)
 74  {
 75     uint8 value;
 76  
 77     value = (uint8) retrieve_type(INP_JOYPAD1);
 78  
 79     /* mask out left/right simultaneous keypresses */
 80     if ((value & INP_PAD_UP) && (value & INP_PAD_DOWN))
 81        value &= ~(INP_PAD_UP | INP_PAD_DOWN);
 82  
 83     if ((value & INP_PAD_LEFT) && (value & INP_PAD_RIGHT))
 84        value &= ~(INP_PAD_LEFT | INP_PAD_RIGHT);
 85  
 86     /* return (0x40 | value) due to bus conflicts */
 87     return (0x40 | ((value >> pad1_readcount++) & 1));
 88  }
 89  
 90  static uint8 get_zapper(void)
 91  {
 92     return (uint8) (retrieve_type(INP_ZAPPER));
 93  }
 94  
 95  static uint8 get_powerpad(void)
 96  {
 97     int value;
 98     uint8 ret_val = 0;
 99     
100     value = retrieve_type(INP_POWERPAD);
101  
102     if (((value >> 8) >> ppad_readcount) & 1)
103        ret_val |= 0x10;
104     if (((value & 0xFF) >> ppad_readcount) & 1)
105        ret_val |= 0x08;
106  
107     ppad_readcount++;
108  
109     return ret_val;
110  }
111  
112  static uint8 get_vsdips0(void)
113  {
114     return (retrieve_type(INP_VSDIPSW0));
115  }
116  
117  static uint8 get_vsdips1(void)
118  {
119     return (retrieve_type(INP_VSDIPSW1));
120  }
121  
122  static uint8 get_arkanoid(void)
123  {
124     uint8 value = retrieve_type(INP_ARKANOID);
125  
126     if ((value >> (7 - ark_readcount++)) & 1)
127        return 0x02;
128     else
129        return 0;
130  }
131  
132  /* return input state for all types indicated (can be ORed together) */
133  uint8 input_get(int types)
134  {
135     uint8 value = 0;
136  
137     if (types & INP_JOYPAD0)
138        value |= get_pad0();
139     if (types & INP_JOYPAD1)
140        value |= get_pad1();
141     if (types & INP_ZAPPER)
142        value |= get_zapper();
143     if (types & INP_POWERPAD)
144        value |= get_powerpad();
145     if (types & INP_VSDIPSW0)
146        value |= get_vsdips0();
147     if (types & INP_VSDIPSW1)
148        value |= get_vsdips1();
149     if (types & INP_ARKANOID)
150        value |= get_arkanoid();
151  
152     return value;
153  }
154  
155  /* register an input type */
156  void input_register(nesinput_t *input)
157  {
158     if (NULL == input)
159        return;
160  
161     nes_input[active_entries] = input;
162     active_entries++;
163  }
164  
165  void input_event(nesinput_t *input, int state, int value)
166  {
167     ASSERT(input);
168  
169     if (state == INP_STATE_MAKE)
170        input->data |= value;   /* OR it in */
171     else /* break state */
172        input->data &= ~value;  /* mask it out */
173  }
174  
175  void input_strobe(void)
176  {
177     pad0_readcount = 0;
178     pad1_readcount = 0;
179     ppad_readcount = 0;
180     ark_readcount = 0;
181  }
182  
183  /*
184  ** $Log: nesinput.c,v $
185  ** Revision 1.2  2001/04/27 14:37:11  neil
186  ** wheeee
187  **
188  ** Revision 1.1.1.1  2001/04/27 07:03:54  neil
189  ** initial
190  **
191  ** Revision 1.1  2000/10/24 12:20:28  matt
192  ** changed directory structure
193  **
194  ** Revision 1.9  2000/09/10 23:25:03  matt
195  ** minor changes
196  **
197  ** Revision 1.8  2000/07/31 04:27:59  matt
198  ** one million cleanups
199  **
200  ** Revision 1.7  2000/07/23 15:11:45  matt
201  ** removed unused variables
202  **
203  ** Revision 1.6  2000/07/17 01:52:28  matt
204  ** made sure last line of all source files is a newline
205  **
206  ** Revision 1.5  2000/07/04 04:56:50  matt
207  ** include changes
208  **
209  ** Revision 1.4  2000/06/09 15:12:26  matt
210  ** initial revision
211  **
212  */