libsidplayfp  2.3.1
lightpen.h
1 /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright 2011-2021 Leandro Nini <drfiemost@users.sourceforge.net>
5  * Copyright 2009-2014 VICE Project
6  * Copyright 2007-2010 Antti Lankila
7  * Copyright 2001 Simon White
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  */
23 
24 #ifndef LIGHTPEN_H
25 #define LIGHTPEN_H
26 
27 namespace libsidplayfp
28 {
29 
34 class Lightpen
35 {
36 private:
38  unsigned int lastLine;
39 
41  unsigned int cyclesPerLine;
42 
44  unsigned int lpx;
45 
47  unsigned int lpy;
48 
50  bool isTriggered;
51 
52 private:
59  uint8_t getXpos(unsigned int lineCycle) const
60  {
61  // FIXME: on NTSC the xpos is not incremented at lineCycle 61
62  if (lineCycle < 13)
63  lineCycle += cyclesPerLine;
64 
65  lineCycle -= 13;
66 
67  // On NTSC the xpos is not incremented at lineCycle 61
68  if ((cyclesPerLine == 65) && (lineCycle > (61 - 13)))
69  {
70  lineCycle--;
71  }
72 
73  return lineCycle << 2;
74  }
75 
76 public:
83  void setScreenSize(unsigned int height, unsigned int width)
84  {
85  lastLine = height - 1;
86  cyclesPerLine = width;
87  }
88 
92  void reset()
93  {
94  lpx = 0;
95  lpy = 0;
96  isTriggered = false;
97  }
98 
102  uint8_t getX() const { return lpx; }
103 
107  uint8_t getY() const { return lpy; }
108 
116  bool retrigger()
117  {
118  if (isTriggered)
119  return false;
120 
121  isTriggered = true;
122 
123  switch (cyclesPerLine)
124  {
125  case 63:
126  default:
127  lpx = 0xd1;
128  break;
129  case 65:
130  lpx = 0xd5;
131  break;
132  }
133 
134  lpy = 0;
135 
136  return true;
137  }
138 
146  bool trigger(unsigned int lineCycle, unsigned int rasterY)
147  {
148  if (isTriggered)
149  return false;
150 
151  isTriggered = true;
152 
153  // don't latch on the last line, except on the first cycle
154  if ((rasterY == lastLine) && (lineCycle > 0))
155  {
156  return false;
157  }
158 
159  // Latch current coordinates
160  lpx = getXpos(lineCycle) + 2; // + 1 for MOS 85XX
161  lpy = rasterY;
162 
163  // On 6569R1 and 6567R56A the interrupt is triggered only
164  // when the line is low on the first cycle of the frame.
165  return true; // false for old chip revisions
166  }
167 
171  void untrigger() { isTriggered = false; }
172 };
173 
174 }
175 
176 #endif
Definition: lightpen.h:35
uint8_t getX() const
Definition: lightpen.h:102
uint8_t getY() const
Definition: lightpen.h:107
void reset()
Definition: lightpen.h:92
bool retrigger()
Definition: lightpen.h:116
bool trigger(unsigned int lineCycle, unsigned int rasterY)
Definition: lightpen.h:146
void setScreenSize(unsigned int height, unsigned int width)
Definition: lightpen.h:83
void untrigger()
Definition: lightpen.h:171