lightpen.h
/*
* This file is part of libsidplayfp, a SID player engine.
*
* Copyright 2011-2021 Leandro Nini <drfiemost@users.sourceforge.net>
* Copyright 2009-2014 VICE Project
* Copyright 2007-2010 Antti Lankila
* Copyright 2001 Simon White
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef LIGHTPEN_H
#define LIGHTPEN_H
namespace libsidplayfp
{
class Lightpen
{
private:
unsigned int lastLine;
unsigned int cyclesPerLine;
unsigned int lpx;
unsigned int lpy;
bool isTriggered;
private:
uint8_t getXpos(unsigned int lineCycle) const
{
if (lineCycle < 13)
lineCycle += cyclesPerLine;
lineCycle -= 13;
// On NTSC the xpos is not incremented at lineCycle 61
if ((cyclesPerLine == 65) && (lineCycle > (61 - 13)))
{
lineCycle--;
}
return lineCycle << 2;
}
public:
void setScreenSize(unsigned int height, unsigned int width)
{
lastLine = height - 1;
cyclesPerLine = width;
}
void reset()
{
lpx = 0;
lpy = 0;
isTriggered = false;
}
uint8_t getX() const { return lpx; }
uint8_t getY() const { return lpy; }
bool retrigger()
{
if (isTriggered)
return false;
isTriggered = true;
switch (cyclesPerLine)
{
case 63:
default:
lpx = 0xd1;
break;
case 65:
lpx = 0xd5;
break;
}
lpy = 0;
return true;
}
bool trigger(unsigned int lineCycle, unsigned int rasterY)
{
if (isTriggered)
return false;
isTriggered = true;
// don't latch on the last line, except on the first cycle
if ((rasterY == lastLine) && (lineCycle > 0))
{
return false;
}
// Latch current coordinates
lpx = getXpos(lineCycle) + 2; // + 1 for MOS 85XX
lpy = rasterY;
// On 6569R1 and 6567R56A the interrupt is triggered only
// when the line is low on the first cycle of the frame.
return true; // false for old chip revisions
}
void untrigger() { isTriggered = false; }
};
}
#endif
libsidplayfp::Lightpen
Definition lightpen.h:35
libsidplayfp::Lightpen::getX
uint8_t getX() const
Definition lightpen.h:101
libsidplayfp::Lightpen::getY
uint8_t getY() const
Definition lightpen.h:106
libsidplayfp::Lightpen::reset
void reset()
Definition lightpen.h:91
libsidplayfp::Lightpen::retrigger
bool retrigger()
Definition lightpen.h:113
libsidplayfp::Lightpen::trigger
bool trigger(unsigned int lineCycle, unsigned int rasterY)
Definition lightpen.h:143
libsidplayfp::Lightpen::setScreenSize
void setScreenSize(unsigned int height, unsigned int width)
Definition lightpen.h:82
libsidplayfp::Lightpen::untrigger
void untrigger()
Definition lightpen.h:168