Browse Source

Digital input support, core run function.

* Emulator inputs are now enumerated and read from the config file.
    * Keyboard inputs are handled and passed to the core.
master
Ian Burgmyer 4 years ago
parent
commit
0ce46e1409
  1. 35
      libplip/Core/PlipChip8.cpp
  2. 27
      libplip/Core/PlipChip8.h
  3. 1
      libplip/Input/PlipInput.h
  4. 6
      libplip/Input/PlipInputDefinition.h
  5. 4
      libplip/Plip.cpp
  6. 1
      libplip/Plip.h
  7. 2
      libplip/PlipCore.h
  8. 23
      plip-sdl/SDL/SdlEvent.cpp
  9. 7
      plip-sdl/SDL/SdlEvent.h
  10. 21
      plip-sdl/main.cpp

35
libplip/Core/PlipChip8.cpp

@ -8,9 +8,31 @@
#include "PlipChip8.h"
#include "../PlipIo.h"
#include <iostream>
namespace Plip::Core {
PlipChip8::PlipChip8(PlipInput *input) : Plip::PlipCore(input) {
m_ram = new PlipMemoryRam(RamSize);
m_memoryMap->AddBlock(m_ram);
m_input->AddInput(0x0, PlipInputDefinition(PlipInputType::Digital, "0"), { .digital = false });
m_input->AddInput(0x1, PlipInputDefinition(PlipInputType::Digital, "1"), { .digital = false });
m_input->AddInput(0x2, PlipInputDefinition(PlipInputType::Digital, "2"), { .digital = false });
m_input->AddInput(0x3, PlipInputDefinition(PlipInputType::Digital, "3"), { .digital = false });
m_input->AddInput(0x4, PlipInputDefinition(PlipInputType::Digital, "4"), { .digital = false });
m_input->AddInput(0x5, PlipInputDefinition(PlipInputType::Digital, "5"), { .digital = false });
m_input->AddInput(0x6, PlipInputDefinition(PlipInputType::Digital, "6"), { .digital = false });
m_input->AddInput(0x7, PlipInputDefinition(PlipInputType::Digital, "7"), { .digital = false });
m_input->AddInput(0x8, PlipInputDefinition(PlipInputType::Digital, "8"), { .digital = false });
m_input->AddInput(0x9, PlipInputDefinition(PlipInputType::Digital, "9"), { .digital = false });
m_input->AddInput(0xA, PlipInputDefinition(PlipInputType::Digital, "A"), { .digital = false });
m_input->AddInput(0xB, PlipInputDefinition(PlipInputType::Digital, "B"), { .digital = false });
m_input->AddInput(0xC, PlipInputDefinition(PlipInputType::Digital, "C"), { .digital = false });
m_input->AddInput(0xD, PlipInputDefinition(PlipInputType::Digital, "D"), { .digital = false });
m_input->AddInput(0xE, PlipInputDefinition(PlipInputType::Digital, "E"), { .digital = false });
m_input->AddInput(0xF, PlipInputDefinition(PlipInputType::Digital, "F"), { .digital = false });
}
void PlipChip8::Delta(long ns) {
}
PlipError PlipChip8::Load(const std::string &path) {
@ -22,15 +44,22 @@ namespace Plip::Core {
// Zero RAM.
for(auto i = 0; i < RamSize; i++)
m_ram->SetByte(i, 0x00);
m_memoryMap->SetByte(i, 0x00);
// Load program.
auto ramByte = ProgramOffset;
auto dataByte = 0;
while(dataByte < size && ramByte < RamSize)
m_ram->SetByte(ramByte++, data[dataByte++]);
m_memoryMap->SetByte(ramByte++, data[dataByte++]);
// Write character set.
WriteCharacterSet(CharacterSet);
m_memoryMap->AddBlock(m_ram);
return PlipError::Success;
}
void PlipChip8::WriteCharacterSet(uint32_t address) {
for(auto i = 0; i < m_charsetLength; i++)
m_memoryMap->SetByte(address + i, m_charset[i]);
}
}

27
libplip/Core/PlipChip8.h

@ -19,12 +19,39 @@ namespace Plip::Core {
public:
explicit PlipChip8(PlipInput *input);
void Delta(long ns) override;
PlipError Load(const std::string &path) override;
static const uint32_t ClockRate = 500;
static constexpr long ClockTime = (1000 / ClockRate) * 1000000;
static const uint32_t CharacterSet = 0x000;
static const uint32_t ProgramOffset = 0x200;
static const uint32_t RamSize = 0x1000;
private:
PlipMemoryRam *m_ram;
std::unordered_map<int, PlipInputDefinition> m_inputList;
void WriteCharacterSet(uint32_t address);
static constexpr uint8_t m_charset[] {
0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
0x20, 0x60, 0x20, 0x20, 0x70, // 1
0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3
0x90, 0x90, 0xF0, 0x10, 0x10, // 4
0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5
0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6
0xF0, 0x10, 0x20, 0x40, 0x40, // 7
0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8
0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9
0xF0, 0x90, 0xF0, 0x90, 0x90, // A
0xE0, 0x90, 0xE0, 0x90, 0xE0, // B
0xF0, 0x80, 0x80, 0x80, 0xF0, // C
0xE0, 0x90, 0x90, 0x90, 0xE0, // D
0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
0xF0, 0x80, 0xF0, 0x80, 0x80 // F
};
static constexpr uint32_t m_charsetLength = 5 * 16;
};
}

1
libplip/Input/PlipInput.h

@ -19,6 +19,7 @@ namespace Plip {
virtual void AddInput(std::unordered_map<int, PlipInputDefinition> inputList);
virtual void ClearInput();
virtual PlipInputData GetInput(int id);
std::unordered_map<int, PlipInputDefinition> GetInputList() { return m_coreInput; }
virtual void UpdateInput(int id, PlipInputData data);
private:

6
libplip/Input/PlipInputDefinition.h

@ -20,9 +20,9 @@ namespace Plip {
public:
PlipInputDefinition(PlipInputType type, const std::string &description);
PlipInputData GetData() const;
std::string GetDescription() const;
PlipInputType GetType() const;
[[nodiscard]] PlipInputData GetData() const;
[[nodiscard]] std::string GetDescription() const;
[[nodiscard]] PlipInputType GetType() const;
void SetData(PlipInputData data);
private:

4
libplip/Plip.cpp

@ -52,4 +52,8 @@ namespace Plip {
return m_core->Load(path);
}
void Plip::Run(long ns) {
m_core->Delta(ns);
}
}

1
libplip/Plip.h

@ -24,6 +24,7 @@ namespace Plip {
PlipInput* GetInput();
PlipVideo* GetVideo();
PlipError Load(PlipValidCore core, const std::string &path);
void Run(long ns);
private:
PlipCore *m_core = nullptr;

2
libplip/PlipCore.h

@ -27,6 +27,7 @@ namespace Plip {
public:
static std::vector<PlipCoreDescription> GetSupportedCores();
virtual void Delta(long ns) = 0;
virtual PlipMemoryMap* GetMemoryMap() final { return m_memoryMap; }
virtual PlipError Load(const std::string &path) = 0;
@ -36,6 +37,7 @@ namespace Plip {
PlipInput *m_input;
PlipMemoryMap *m_memoryMap = new PlipMemoryMap();
private:
static constexpr PlipCoreDescription m_supportedCores[] = {
{
"chip8",

23
plip-sdl/SDL/SdlEvent.cpp

@ -8,12 +8,29 @@
#include "SdlEvent.h"
namespace PlipSdl {
void SdlEvent::AddDigitalBinding(int id, SDL_Scancode scancode) {
m_digitalBinding.insert(std::pair<SDL_Scancode, int>(scancode, id));
}
void SdlEvent::AddDigitalBinding(int id, const std::string &binding) {
auto scancode = SDL_GetScancodeFromName(binding.c_str());
AddDigitalBinding(id, scancode);
}
SdlUiEvent SdlEvent::ProcessEvents() {
SDL_Event ev;
auto uiEvent = SdlUiEvent::None;
while(SDL_PollEvent(&ev)) {
switch(ev.type) {
case SDL_KEYDOWN:
UpdateDigitalInput(ev.key.keysym.scancode, true);
break;
case SDL_KEYUP:
UpdateDigitalInput(ev.key.keysym.scancode, false);
break;
case SDL_QUIT:
uiEvent = SdlUiEvent::Quit;
break;
@ -22,4 +39,10 @@ namespace PlipSdl {
return uiEvent;
}
void SdlEvent::UpdateDigitalInput(SDL_Scancode scancode, bool value) {
auto it = m_digitalBinding.find(scancode);
if(it == m_digitalBinding.cend()) return;
m_input->UpdateInput(it->second, { .digital = value });
}
}

7
plip-sdl/SDL/SdlEvent.h

@ -5,6 +5,8 @@
#pragma once
#include <SDL.h>
#include "Input/PlipInput.h"
namespace PlipSdl {
@ -17,9 +19,14 @@ namespace PlipSdl {
public:
explicit SdlEvent(Plip::PlipInput *input) : m_input(input) {};
void AddDigitalBinding(int id, SDL_Scancode scancode);
void AddDigitalBinding(int id, const std::string &binding);
SdlUiEvent ProcessEvents();
private:
void UpdateDigitalInput(SDL_Scancode scancode, bool value);
std::unordered_map<SDL_Scancode, int> m_digitalBinding;
Plip::PlipInput *m_input;
};
}

21
plip-sdl/main.cpp

@ -30,12 +30,9 @@ std::vector<std::vector<std::string>> intParamMapping = {
{ "fps" , "video", "targetFps" }
};
void gameLoop(Plip::Plip *plip, PlipSdl::Config *config, PlipSdl::Timer *timer) {
auto input = plip->GetInput();
void gameLoop(Plip::Plip *plip, PlipSdl::Config *config, PlipSdl::SdlEvent *event, PlipSdl::Timer *timer) {
auto video = plip->GetVideo();
auto event = new PlipSdl::SdlEvent(input);
auto targetFps = config->GetValue<int>("video", "targetFps");
auto frameTime = 1000000000 / targetFps;
@ -46,6 +43,8 @@ void gameLoop(Plip::Plip *plip, PlipSdl::Config *config, PlipSdl::Timer *timer)
if(event->ProcessEvents() == PlipSdl::SdlUiEvent::Quit)
running = false;
plip->Run(frameTime);
auto time = timer->StopwatchStop();
auto delay = frameTime - time;
while(delay < 0)
@ -197,7 +196,19 @@ int main(int argc, char **argv) {
break;
}
gameLoop(plip, config, timer);
auto input = plip->GetInput();
auto event = new PlipSdl::SdlEvent(input);
// Load inputs for the active core.
std::string section = "input." + coreName;
for(const auto& coreInput : input->GetInputList()) {
auto key = config->GetValue(section, coreInput.second.GetDescription());
if(key == config->empty) continue;
event->AddDigitalBinding(coreInput.first, key);
}
gameLoop(plip, config, event, timer);
SDL_Quit();
return 0;

Loading…
Cancel
Save