Input
This commit is contained in:
parent
b1265da7d3
commit
f6e339105a
|
@ -14,6 +14,7 @@ target_sources(
|
|||
Source/CPU/CPU.cpp
|
||||
Source/CPU/AddressModes.cpp
|
||||
Source/CPU/Instructions.cpp
|
||||
Source/Input.cpp
|
||||
Source/NES.cpp
|
||||
Source/Platform.cpp
|
||||
Source/PPU/PPU.cpp
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
#include "Input.hpp"
|
||||
|
||||
|
||||
void Input::Strobe(uint8_t* but)
|
||||
{
|
||||
if (strobe)
|
||||
{
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
buttons[i] = but[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t Input::Poll()
|
||||
{
|
||||
uint8_t buttonState;
|
||||
|
||||
// Strobe set - return state of A button
|
||||
if (strobe)
|
||||
{
|
||||
buttonState = buttons[Buttons::A];
|
||||
}
|
||||
|
||||
// All 8 bits read - return 1u
|
||||
else if (buttonIndex > Buttons::Right)
|
||||
{
|
||||
buttonState = 1u;
|
||||
}
|
||||
|
||||
// Return next bit
|
||||
else
|
||||
{
|
||||
buttonState = buttons[buttonIndex];
|
||||
|
||||
++buttonIndex;
|
||||
}
|
||||
|
||||
return buttonState;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
enum Buttons
|
||||
{
|
||||
A = 0,
|
||||
B = 1,
|
||||
Select = 2,
|
||||
Start = 3,
|
||||
Up = 4,
|
||||
Down = 5,
|
||||
Left = 6,
|
||||
Right = 7
|
||||
};
|
||||
|
||||
|
||||
class Input
|
||||
{
|
||||
public:
|
||||
void Strobe(uint8_t* but);
|
||||
uint8_t Poll();
|
||||
|
||||
private:
|
||||
friend class NES;
|
||||
|
||||
bool strobe{};
|
||||
uint8_t buttonIndex{};
|
||||
uint8_t buttons[8]{};
|
||||
};
|
|
@ -44,7 +44,8 @@ NES::NES()
|
|||
: cpu(std::make_unique<CPU>()),
|
||||
ppu(std::make_unique<PPU>()),
|
||||
cartridge(std::make_unique<Cartridge>()),
|
||||
platform(std::make_unique<Platform>("NES", WINDOW_WIDTH, WINDOW_HEIGHT, VIDEO_WIDTH, VIDEO_HEIGHT))
|
||||
platform(std::make_unique<Platform>("NES", WINDOW_WIDTH, WINDOW_HEIGHT, VIDEO_WIDTH, VIDEO_HEIGHT)),
|
||||
input(std::make_unique<Input>())
|
||||
{
|
||||
ppu->nes = this;
|
||||
|
||||
|
@ -123,10 +124,14 @@ void NES::InsertCartridge(char const* filename)
|
|||
|
||||
void NES::Run()
|
||||
{
|
||||
while (!platform->ProcessInput())
|
||||
uint8_t buttons[8]{};
|
||||
|
||||
while (!platform->ProcessInput(buttons))
|
||||
{
|
||||
cpu->Cycle();
|
||||
|
||||
input->Strobe(buttons);
|
||||
|
||||
uint8_t cpuCyclesTaken = (cpu->cycles - cpu->prevCycles) * 3u;
|
||||
|
||||
ppu->Cycle(cpuCyclesTaken);
|
||||
|
@ -166,6 +171,7 @@ void NES::Write(BusSource source, uint16_t address, uint8_t value)
|
|||
{
|
||||
uint16_t index = address & 0x1Fu;
|
||||
|
||||
// PPU OAM
|
||||
if (index == 0x14u)
|
||||
{
|
||||
uint8_t addrMsb = value;
|
||||
|
@ -177,6 +183,20 @@ void NES::Write(BusSource source, uint16_t address, uint8_t value)
|
|||
ppu->oam[ppu->oamAddr + addrLsb] = Read(BusSource::CPU, addr);
|
||||
}
|
||||
}
|
||||
|
||||
// Controller
|
||||
else if (index == 0x16u)
|
||||
{
|
||||
if (value & 0x1u)
|
||||
{
|
||||
input->strobe = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
input->strobe = false;
|
||||
input->buttonIndex = 0u;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Expansion I/O
|
||||
|
@ -253,6 +273,13 @@ uint8_t NES::Read(BusSource source, uint16_t address)
|
|||
// APU and IO
|
||||
else if (address < 0x4020u)
|
||||
{
|
||||
uint16_t index = address & 0x1Fu;
|
||||
|
||||
// Controller
|
||||
if (index == 0x16u)
|
||||
{
|
||||
byte = input->Poll();
|
||||
}
|
||||
}
|
||||
|
||||
// Expansion I/O
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Cartridge.hpp"
|
||||
#include "CPU/CPU.hpp"
|
||||
#include "Input.hpp"
|
||||
#include "Platform.hpp"
|
||||
#include "PPU/PPU.hpp"
|
||||
#include <memory>
|
||||
|
@ -45,6 +46,7 @@ public:
|
|||
std::unique_ptr<PPU> ppu;
|
||||
std::unique_ptr<Cartridge> cartridge;
|
||||
std::unique_ptr<Platform> platform;
|
||||
std::unique_ptr<Input> input;
|
||||
|
||||
bool nmi{};
|
||||
Color palette[64];
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "Platform.hpp"
|
||||
#include "Input.hpp"
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
|
||||
|
@ -30,7 +31,7 @@ void Platform::Update(void const* buffer, int pitch)
|
|||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
bool Platform::ProcessInput()
|
||||
bool Platform::ProcessInput(uint8_t* buttons)
|
||||
{
|
||||
bool quit = false;
|
||||
|
||||
|
@ -55,6 +56,95 @@ bool Platform::ProcessInput()
|
|||
quit = true;
|
||||
break;
|
||||
}
|
||||
case SDLK_UP:
|
||||
{
|
||||
{buttons[Buttons::Up] = 1u;}
|
||||
break;
|
||||
}
|
||||
case SDLK_DOWN:
|
||||
{
|
||||
{buttons[Buttons::Down] = 1u;}
|
||||
break;
|
||||
}
|
||||
case SDLK_LEFT:
|
||||
{
|
||||
{buttons[Buttons::Left] = 1u;}
|
||||
break;
|
||||
}
|
||||
case SDLK_RIGHT:
|
||||
{
|
||||
{buttons[Buttons::Right] = 1u;}
|
||||
break;
|
||||
}
|
||||
case SDLK_LSHIFT:
|
||||
{
|
||||
buttons[Buttons::Select] = 1u;
|
||||
break;
|
||||
}
|
||||
case SDLK_RETURN:
|
||||
{
|
||||
{buttons[Buttons::Start] = 1u;}
|
||||
break;
|
||||
}
|
||||
case SDLK_z:
|
||||
{
|
||||
{buttons[Buttons::A] = 1u;}
|
||||
break;
|
||||
}
|
||||
case SDLK_x:
|
||||
{
|
||||
{buttons[Buttons::B] = 1u;}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
switch (event.key.keysym.sym)
|
||||
{
|
||||
case SDLK_UP:
|
||||
{
|
||||
{buttons[Buttons::Up] = 0u;}
|
||||
break;
|
||||
}
|
||||
case SDLK_DOWN:
|
||||
{
|
||||
{buttons[Buttons::Down] = 0u;}
|
||||
break;
|
||||
}
|
||||
case SDLK_LEFT:
|
||||
{
|
||||
{buttons[Buttons::Left] = 0u;}
|
||||
break;
|
||||
}
|
||||
case SDLK_RIGHT:
|
||||
{
|
||||
{buttons[Buttons::Right] = 0u;}
|
||||
break;
|
||||
}
|
||||
case SDLK_LSHIFT:
|
||||
{
|
||||
{buttons[Buttons::Select] = 0u;}
|
||||
break;
|
||||
}
|
||||
case SDLK_RETURN:
|
||||
{
|
||||
{buttons[Buttons::Start] = 0u;}
|
||||
break;
|
||||
}
|
||||
case SDLK_z:
|
||||
{
|
||||
{buttons[Buttons::A] = 0u;}
|
||||
break;
|
||||
}
|
||||
case SDLK_x:
|
||||
{
|
||||
{buttons[Buttons::B] = 0u;}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -62,5 +152,6 @@ bool Platform::ProcessInput()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
return quit;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "Input.hpp"
|
||||
|
||||
|
||||
class SDL_Window;
|
||||
|
@ -14,7 +15,7 @@ public:
|
|||
Platform(char const* title, int windowWidth, int windowHeight, int textureWidth, int textureHeight);
|
||||
~Platform();
|
||||
void Update(void const* buffer, int pitch);
|
||||
bool ProcessInput();
|
||||
bool ProcessInput(uint8_t* buttons);
|
||||
|
||||
SDL_Window* window{};
|
||||
SDL_Renderer* renderer{};
|
||||
|
|
Loading…
Reference in New Issue