libsidplayfp 2.3.0
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
27namespace libsidplayfp
28{
29
35{
36private:
38 unsigned int lastLine;
39
41 unsigned int cyclesPerLine;
42
44 unsigned int lpx;
45
47 unsigned int lpy;
48
50 bool isTriggered;
51
52private:
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
76public:
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
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