libsidplayfp 2.15.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 if (lineCycle < 13)
62 lineCycle += cyclesPerLine;
63
64 lineCycle -= 13;
65
66 // On NTSC the xpos is not incremented at lineCycle 61
67 if ((cyclesPerLine == 65) && (lineCycle > (61 - 13)))
68 {
69 lineCycle--;
70 }
71
72 return lineCycle << 2;
73 }
74
75public:
82 void setScreenSize(unsigned int height, unsigned int width)
83 {
84 lastLine = height - 1;
85 cyclesPerLine = width;
86 }
87
91 void reset()
92 {
93 lpx = 0;
94 lpy = 0;
95 isTriggered = false;
96 }
97
101 uint8_t getX() const { return lpx; }
102
106 uint8_t getY() const { return lpy; }
107
114 {
115 if (isTriggered)
116 return false;
117
118 isTriggered = true;
119
120 switch (cyclesPerLine)
121 {
122 case 63:
123 default:
124 lpx = 0xd1;
125 break;
126 case 65:
127 lpx = 0xd5;
128 break;
129 }
130
131 lpy = 0;
132
133 return true;
134 }
135
143 bool trigger(unsigned int lineCycle, unsigned int rasterY)
144 {
145 if (isTriggered)
146 return false;
147
148 isTriggered = true;
149
150 // don't latch on the last line, except on the first cycle
151 if ((rasterY == lastLine) && (lineCycle > 0))
152 {
153 return false;
154 }
155
156 // Latch current coordinates
157 lpx = getXpos(lineCycle) + 2; // + 1 for MOS 85XX
158 lpy = rasterY;
159
160 // On 6569R1 and 6567R56A the interrupt is triggered only
161 // when the line is low on the first cycle of the frame.
162 return true; // false for old chip revisions
163 }
164
168 void untrigger() { isTriggered = false; }
169};
170
171}
172
173#endif
Definition lightpen.h:35
uint8_t getX() const
Definition lightpen.h:101
uint8_t getY() const
Definition lightpen.h:106
void reset()
Definition lightpen.h:91
bool retrigger()
Definition lightpen.h:113
bool trigger(unsigned int lineCycle, unsigned int rasterY)
Definition lightpen.h:143
void setScreenSize(unsigned int height, unsigned int width)
Definition lightpen.h:82
void untrigger()
Definition lightpen.h:168