2016-02-05 23:14:27 -05:00
|
|
|
#pragma once
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "BaseControlDevice.h"
|
2017-11-19 23:08:23 -05:00
|
|
|
#include "KeyManager.h"
|
|
|
|
#include "IKeyManager.h"
|
|
|
|
#include "PPU.h"
|
2016-02-05 23:14:27 -05:00
|
|
|
|
2017-11-19 23:08:23 -05:00
|
|
|
class Zapper : public BaseControlDevice
|
2016-06-22 19:23:08 -04:00
|
|
|
{
|
2017-11-19 23:08:23 -05:00
|
|
|
protected:
|
|
|
|
bool HasCoordinates() override { return true; }
|
|
|
|
|
|
|
|
string GetKeyNames() override
|
2016-06-22 19:23:08 -04:00
|
|
|
{
|
2017-11-19 23:08:23 -05:00
|
|
|
return "F";
|
2016-06-22 19:23:08 -04:00
|
|
|
}
|
|
|
|
|
2017-11-19 23:08:23 -05:00
|
|
|
enum Buttons { Fire };
|
2016-02-05 23:14:27 -05:00
|
|
|
|
2017-11-19 23:08:23 -05:00
|
|
|
void InternalSetStateFromInput() override
|
|
|
|
{
|
|
|
|
if(EmulationSettings::InputEnabled()) {
|
|
|
|
SetPressedState(Buttons::Fire, KeyManager::IsMouseButtonPressed(MouseButton::LeftButton));
|
|
|
|
}
|
|
|
|
|
|
|
|
MousePosition pos = KeyManager::GetMousePosition();
|
|
|
|
if(KeyManager::IsMouseButtonPressed(MouseButton::RightButton)) {
|
|
|
|
pos.X = -1;
|
|
|
|
pos.Y = -1;
|
|
|
|
}
|
|
|
|
SetCoordinates(pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsLightFound()
|
|
|
|
{
|
|
|
|
return StaticIsLightFound(GetCoordinates());
|
|
|
|
}
|
2016-02-05 23:14:27 -05:00
|
|
|
|
|
|
|
public:
|
2017-11-19 23:08:23 -05:00
|
|
|
Zapper(uint8_t port) : BaseControlDevice(port)
|
|
|
|
{
|
|
|
|
}
|
2016-02-05 23:14:27 -05:00
|
|
|
|
2017-11-19 23:08:23 -05:00
|
|
|
uint8_t ReadRAM(uint16_t addr) override
|
|
|
|
{
|
|
|
|
uint8_t output = 0;
|
2017-12-28 14:44:20 -05:00
|
|
|
if((IsExpansionDevice() && addr == 0x4017) || IsCurrentPort(addr)) {
|
2017-11-19 23:08:23 -05:00
|
|
|
output = (IsLightFound() ? 0 : 0x08) | (IsPressed(Zapper::Buttons::Fire) ? 0x10 : 0x00);
|
|
|
|
}
|
|
|
|
return output;
|
|
|
|
}
|
2016-02-05 23:14:27 -05:00
|
|
|
|
2017-11-19 23:08:23 -05:00
|
|
|
void WriteRAM(uint16_t addr, uint8_t value) override
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool StaticIsLightFound(MousePosition pos)
|
|
|
|
{
|
|
|
|
int32_t scanline = PPU::GetCurrentScanline();
|
|
|
|
int32_t cycle = PPU::GetCurrentCycle();
|
|
|
|
int radius = (int)EmulationSettings::GetZapperDetectionRadius();
|
|
|
|
|
|
|
|
if(pos.X >= 0 && pos.Y >= 0) {
|
|
|
|
for(int yOffset = -radius; yOffset <= radius; yOffset++) {
|
|
|
|
int yPos = pos.Y + yOffset;
|
|
|
|
if(yPos >= 0 && yPos < PPU::ScreenHeight) {
|
|
|
|
for(int xOffset = -radius; xOffset <= radius; xOffset++) {
|
|
|
|
int xPos = pos.X + xOffset;
|
|
|
|
if(xPos >= 0 && xPos < PPU::ScreenWidth) {
|
|
|
|
if(scanline >= yPos && (scanline - yPos <= 20) && (scanline != yPos || cycle > xPos) && PPU::GetPixelBrightness(xPos, yPos) >= 85) {
|
|
|
|
//Light cannot be detected if the Y/X position is further ahead than the PPU, or if the PPU drew a dark color
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2016-02-05 23:14:27 -05:00
|
|
|
};
|