Browse Source

Pixel format conversion, and moved a ton of files.

* Implemented a format-agnostic way of plotting pixels and getting the
      number of bytes per pixel.
    * PlipInput can no longer be inherited.
    * Added width/height getters to the video subsystem.
    * Properly initialized SDL2 and added a temporary event loop (required to
      get the window to appear on macOS).
    * Sorted all source files into appropriately named directories.
master
Ian Burgmyer 4 years ago
parent
commit
46613bdfa1
  1. 23
      CMakeLists.txt
  2. 0
      libplip/Input/PlipInput.cpp
  3. 15
      libplip/Input/PlipInput.h
  4. 0
      libplip/Input/PlipInputDefinition.cpp
  5. 0
      libplip/Input/PlipInputDefinition.h
  6. 0
      libplip/Memory/PlipMemory.h
  7. 0
      libplip/Memory/PlipMemoryMap.cpp
  8. 0
      libplip/Memory/PlipMemoryMap.h
  9. 0
      libplip/Memory/PlipMemoryRam.cpp
  10. 0
      libplip/Memory/PlipMemoryRam.h
  11. 0
      libplip/Memory/PlipMemoryRom.cpp
  12. 0
      libplip/Memory/PlipMemoryRom.h
  13. 3
      libplip/Plip.cpp
  14. 8
      libplip/Plip.h
  15. 35
      libplip/PlipVideo.h
  16. 46
      libplip/Video/PlipVideo.cpp
  17. 77
      libplip/Video/PlipVideo.h
  18. 0
      libplip/Video/PlipVideoException.h
  19. 0
      plip-sdl/SDL/SdlEvent.cpp
  20. 13
      plip-sdl/SDL/SdlEvent.h
  21. 91
      plip-sdl/SDL/SdlWindow.cpp
  22. 5
      plip-sdl/SDL/SdlWindow.h
  23. 15
      plip-sdl/SdlEvent.h
  24. 0
      plip-sdl/Timer/Timer.h
  25. 0
      plip-sdl/Timer/TimerPosix.cpp
  26. 0
      plip-sdl/Timer/TimerPosix.h
  27. 0
      plip-sdl/Timer/TimerSdl.cpp
  28. 0
      plip-sdl/Timer/TimerSdl.h
  29. 29
      plip-sdl/main.cpp

23
CMakeLists.txt

@ -33,13 +33,18 @@ add_custom_target(
add_library(${lib_name}
libplip/Plip.cpp
libplip/PlipInput.cpp
libplip/PlipInputDefinition.cpp
libplip/PlipMemoryMap.cpp
libplip/PlipMemoryRam.cpp
libplip/PlipMemoryRom.cpp
libplip/Input/PlipInput.cpp
libplip/Input/PlipInputDefinition.cpp
libplip/Memory/PlipMemoryMap.cpp
libplip/Memory/PlipMemoryRam.cpp
libplip/Memory/PlipMemoryRom.cpp
libplip/Video/PlipVideo.cpp
)
if(BIG_ENDIAN)
target_compile_definitions(${lib_name} PRIVATE CORE_BIG_ENDIAN)
endif()
add_dependencies(${lib_name} GENERATE_LIB_VERSION_HEADER)
########
@ -47,17 +52,17 @@ add_dependencies(${lib_name} GENERATE_LIB_VERSION_HEADER)
########
add_executable(${gui_name}
plip-sdl/main.cpp
plip-sdl/SdlEvent.cpp
plip-sdl/SdlWindow.cpp
plip-sdl/SDL/SdlEvent.cpp
plip-sdl/SDL/SdlWindow.cpp
)
if(UNIX)
target_sources(${gui_name} PRIVATE
plip-sdl/TimerPosix.cpp
plip-sdl/Timer/TimerPosix.cpp
)
else()
target_sources(${gui_name} PRIVATE
plip-sdl/TimerSdl.cpp
plip-sdl/Timer/TimerSdl.cpp
)
endif()

0
libplip/PlipInput.cpp → libplip/Input/PlipInput.cpp

15
libplip/PlipInput.h → libplip/Input/PlipInput.h

@ -11,17 +11,16 @@
#include "PlipInputDefinition.h"
namespace Plip {
class PlipInput {
class PlipInput final {
public:
virtual void AddInput(int id, const PlipInputDefinition &input, const PlipInputData &initialData) final;
virtual void AddInput(std::unordered_map<int, PlipInputDefinition> inputList) final;
virtual void ClearInput() final;
virtual PlipInputData GetInput(int id) final;
virtual void UpdateInput(int id, PlipInputData data) final;
protected:
PlipInput() = default;
virtual void AddInput(int id, const PlipInputDefinition &input, const PlipInputData &initialData);
virtual void AddInput(std::unordered_map<int, PlipInputDefinition> inputList);
virtual void ClearInput();
virtual PlipInputData GetInput(int id);
virtual void UpdateInput(int id, PlipInputData data);
private:
std::unordered_map<int, PlipInputDefinition> m_coreInput;
};

0
libplip/PlipInputDefinition.cpp → libplip/Input/PlipInputDefinition.cpp

0
libplip/PlipInputDefinition.h → libplip/Input/PlipInputDefinition.h

0
libplip/PlipMemory.h → libplip/Memory/PlipMemory.h

0
libplip/PlipMemoryMap.cpp → libplip/Memory/PlipMemoryMap.cpp

0
libplip/PlipMemoryMap.h → libplip/Memory/PlipMemoryMap.h

0
libplip/PlipMemoryRam.cpp → libplip/Memory/PlipMemoryRam.cpp

0
libplip/PlipMemoryRam.h → libplip/Memory/PlipMemoryRam.h

0
libplip/PlipMemoryRom.cpp → libplip/Memory/PlipMemoryRom.cpp

0
libplip/PlipMemoryRom.h → libplip/Memory/PlipMemoryRom.h

3
libplip/Plip.cpp

@ -7,8 +7,7 @@
#include "PlipVersion.h"
namespace Plip {
Plip::Plip(PlipInput *input, PlipVideo *video) {
m_input = input;
Plip::Plip(PlipVideo *video) {
m_video = video;
}

8
libplip/Plip.h

@ -7,13 +7,13 @@
#include <string>
#include "PlipInput.h"
#include "PlipVideo.h"
#include "Input/PlipInput.h"
#include "Video/PlipVideo.h"
namespace Plip {
class Plip {
public:
Plip(PlipInput *input, PlipVideo *video);
explicit Plip(PlipVideo *video);
static std::string GetVersion();
@ -21,7 +21,7 @@ namespace Plip {
PlipVideo* GetVideo();
private:
PlipInput *m_input;
PlipInput *m_input = new PlipInput();
PlipVideo *m_video;
};
}

35
libplip/PlipVideo.h

@ -1,35 +0,0 @@
/* PlipVideo.h
*
* Provides a toolkit-agnostic video interface.
*/
#pragma once
#include <string>
namespace Plip {
enum class PlipVideoFormat {
Unknown,
RGB888,
BGR888,
ARGB8888,
ABGR8888,
RGBA8888,
BGRA8888
};
class PlipVideo {
public:
virtual bool BeginDraw() = 0;
virtual void Draw(void *data) = 0;
virtual void Clear() = 0;
virtual bool EndDraw() = 0;
virtual PlipVideoFormat GetFormat() = 0;
virtual void Resize(int width, int height) = 0;
virtual void SetTitle(std::string title) = 0;
virtual void Render() = 0;
protected:
PlipVideo() = default;
};
}

46
libplip/Video/PlipVideo.cpp

@ -0,0 +1,46 @@
/* PlipVideo.cpp
*
* Provides a toolkit-agnostic video interface.
*/
#include "PlipVideo.h"
#include "PlipVideoException.h"
namespace Plip {
PlipVideoFormatInfo PlipVideo::GetFormatInfo(PlipVideoFormat format) {
switch(format) {
case PlipVideoFormat::RGB888:
return { .pixelWidth = 3, .plot = PlipVideo::PlotRgb888 };
case PlipVideoFormat::BGR888:
return { .pixelWidth = 3, .plot = PlipVideo::PlotBgr888 };
case PlipVideoFormat::XRGB8888:
return { .pixelWidth = 4, .plot = PlipVideo::PlotArgb8888 };
case PlipVideoFormat::XBGR8888:
return { .pixelWidth = 4, .plot = PlipVideo::PlotAbgr8888 };
case PlipVideoFormat::ARGB8888:
return { .pixelWidth = 4, .plot = PlipVideo::PlotArgb8888 };
case PlipVideoFormat::ABGR8888:
return { .pixelWidth = 4, .plot = PlipVideo::PlotAbgr8888 };
case PlipVideoFormat::RGBX8888:
return { .pixelWidth = 4, .plot = PlipVideo::PlotRgba8888 };
case PlipVideoFormat::BGRX8888:
return { .pixelWidth = 4, .plot = PlipVideo::PlotBgra8888 };
case PlipVideoFormat::RGBA8888:
return { .pixelWidth = 4, .plot = PlipVideo::PlotRgba8888 };
case PlipVideoFormat::BGRA8888:
return { .pixelWidth = 4, .plot = PlipVideo::PlotBgra8888 };
default:
throw PlipVideoException("Unsupported pixel format.");
}
}
}

77
libplip/Video/PlipVideo.h

@ -0,0 +1,77 @@
/* PlipVideo.h
*
* Provides a toolkit-agnostic video interface.
*/
#pragma once
#include <string>
namespace Plip {
enum class PlipVideoFormat {
Unknown,
RGB888,
BGR888,
XRGB8888,
XBGR8888,
ARGB8888,
ABGR8888,
RGBX8888,
BGRX8888,
RGBA8888,
BGRA8888
};
struct PlipVideoFormatInfo {
uint8_t pixelWidth;
void (*plot)(void* data, int offset, uint8_t r, uint8_t g, uint8_t b);
};
class PlipVideo {
public:
virtual bool BeginDraw() = 0;
virtual void Draw(void *data) = 0;
virtual void Clear() = 0;
virtual bool EndDraw() = 0;
virtual PlipVideoFormat GetFormat() = 0;
virtual int GetHeight() = 0;
virtual int GetWidth() = 0;
virtual void Resize(int width, int height) = 0;
virtual void SetTitle(std::string title) = 0;
virtual void Render() = 0;
static PlipVideoFormatInfo GetFormatInfo(PlipVideoFormat format);
// Pixel format functions.
static void PlotRgb888(void *data, int offset, uint8_t r, uint8_t g, uint8_t b) {
((uint8_t*)data)[offset * 3] = r;
((uint8_t*)data)[offset * 3 + 1] = g;
((uint8_t*)data)[offset * 3 + 2] = b;
}
static void PlotBgr888(void *data, int offset, uint8_t r, uint8_t g, uint8_t b) {
((uint8_t*)data)[offset * 3] = b;
((uint8_t*)data)[offset * 3 + 1] = g;
((uint8_t*)data)[offset * 3 + 2] = r;
}
static void PlotArgb8888(void *data, int offset, uint8_t r, uint8_t g, uint8_t b) {
((uint32_t*)data)[offset] = (0xFF << 24) + (r << 16) + (g << 8) + b;
}
static void PlotAbgr8888(void *data, int offset, uint8_t r, uint8_t g, uint8_t b) {
((uint32_t*)data)[offset] = (0xFF << 24) + (b << 16) + (g << 8) + r;
}
static void PlotRgba8888(void *data, int offset, uint8_t r, uint8_t g, uint8_t b) {
((uint32_t*)data)[offset] = (r << 24) + (g << 16) + (b << 8) + 0xFF;
}
static void PlotBgra8888(void *data, int offset, uint8_t r, uint8_t g, uint8_t b) {
((uint32_t*)data)[offset] = (b << 24) + (g << 16) + (r << 8) + 0xFF;
}
protected:
PlipVideo() = default;
};
}

0
libplip/PlipVideoException.h → libplip/Video/PlipVideoException.h

0
plip-sdl/SdlEvent.cpp → plip-sdl/SDL/SdlEvent.cpp

13
plip-sdl/SDL/SdlEvent.h

@ -0,0 +1,13 @@
/* SdlEvent.h
*
* An SDL2 event handler.
*/
#pragma once
#include "Input/PlipInput.h"
namespace PlipSdl {
class SdlEvent {
};
}

91
plip-sdl/SdlWindow.cpp → plip-sdl/SDL/SdlWindow.cpp

@ -5,7 +5,7 @@
#include <sstream>
#include "PlipVideoException.h"
#include "Video/PlipVideoException.h"
#include "SdlWindow.h"
@ -15,6 +15,8 @@ namespace PlipSdl {
m_scale = scale;
SDL_InitSubSystem(SDL_INIT_VIDEO);
// Try to create a window.
m_window = SDL_CreateWindow(title.c_str(),
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
@ -75,29 +77,7 @@ namespace PlipSdl {
void SdlWindow::CreateTexture() {
if(m_texture != nullptr) SDL_DestroyTexture(m_texture);
uint32_t pixelFormat;
switch(m_format) {
case Plip::PlipVideoFormat::RGB888:
pixelFormat = SDL_PIXELFORMAT_RGB888;
break;
case Plip::PlipVideoFormat::BGR888:
pixelFormat = SDL_PIXELFORMAT_BGR888;
break;
case Plip::PlipVideoFormat::ARGB8888:
pixelFormat = SDL_PIXELFORMAT_ARGB8888;
break;
case Plip::PlipVideoFormat::ABGR8888:
pixelFormat = SDL_PIXELFORMAT_ABGR8888;
break;
case Plip::PlipVideoFormat::RGBA8888:
pixelFormat = SDL_PIXELFORMAT_RGBA8888;
break;
case Plip::PlipVideoFormat::BGRA8888:
pixelFormat = SDL_PIXELFORMAT_BGRA8888;
break;
default:
throw Plip::PlipVideoException("Unsupported pixel format.");
}
uint32_t pixelFormat = SelectSdlFormat(m_format);
m_texture = nullptr;
m_texture = SDL_CreateTexture(m_renderer,
@ -124,6 +104,14 @@ namespace PlipSdl {
return m_format;
}
int SdlWindow::GetHeight() {
return m_height;
}
int SdlWindow::GetWidth() {
return m_width;
}
void SdlWindow::Render() {
SDL_RenderCopy(m_renderer, m_texture, nullptr, nullptr);
SDL_RenderPresent(m_renderer);
@ -142,29 +130,80 @@ namespace PlipSdl {
bool SdlWindow::SelectFormat(uint32_t format) {
switch(format) {
case SDL_PIXELFORMAT_RGB888:
case SDL_PIXELFORMAT_RGB24:
m_format = Plip::PlipVideoFormat::RGB888;
return true;
case SDL_PIXELFORMAT_BGR888:
case SDL_PIXELFORMAT_BGR24:
m_format = Plip::PlipVideoFormat::BGR888;
return true;
case SDL_PIXELFORMAT_RGB888:
m_format = Plip::PlipVideoFormat::XRGB8888;
return true;
case SDL_PIXELFORMAT_BGR888:
m_format = Plip::PlipVideoFormat::XBGR8888;
return true;
case SDL_PIXELFORMAT_ARGB8888:
m_format = Plip::PlipVideoFormat::ARGB8888;
return true;
case SDL_PIXELFORMAT_ABGR8888:
m_format = Plip::PlipVideoFormat::ABGR8888;
return true;
case SDL_PIXELFORMAT_RGBX8888:
m_format = Plip::PlipVideoFormat::RGBX8888;
return true;
case SDL_PIXELFORMAT_BGRX8888:
m_format = Plip::PlipVideoFormat::BGRX8888;
return true;
case SDL_PIXELFORMAT_RGBA8888:
m_format = Plip::PlipVideoFormat::RGBA8888;
return true;
case SDL_PIXELFORMAT_BGRA8888:
m_format = Plip::PlipVideoFormat::BGRA8888;
return true;
default:
return false;
}
}
uint32_t SdlWindow::SelectSdlFormat(Plip::PlipVideoFormat format) {
switch(format) {
case Plip::PlipVideoFormat::RGB888:
return SDL_PIXELFORMAT_RGB24;
case Plip::PlipVideoFormat::BGR888:
return SDL_PIXELFORMAT_BGR24;
case Plip::PlipVideoFormat::XRGB8888:
case Plip::PlipVideoFormat::ARGB8888:
return SDL_PIXELFORMAT_ARGB8888;
case Plip::PlipVideoFormat::XBGR8888:
case Plip::PlipVideoFormat::ABGR8888:
return SDL_PIXELFORMAT_ABGR8888;
case Plip::PlipVideoFormat::RGBX8888:
case Plip::PlipVideoFormat::RGBA8888:
return SDL_PIXELFORMAT_RGBA8888;
case Plip::PlipVideoFormat::BGRX8888:
case Plip::PlipVideoFormat::BGRA8888:
return SDL_PIXELFORMAT_BGRA8888;
default:
throw Plip::PlipVideoException("Unsupported pixel format.");
}
}
void SdlWindow::SetScale(int scale) {
m_scale = scale;
SDL_SetWindowSize(m_window, m_width * m_scale, m_height * m_scale);

5
plip-sdl/SdlWindow.h → plip-sdl/SDL/SdlWindow.h

@ -7,7 +7,7 @@
#include <SDL.h>
#include "PlipVideo.h"
#include "Video/PlipVideo.h"
namespace PlipSdl {
class SdlWindow : public Plip::PlipVideo {
@ -20,6 +20,8 @@ namespace PlipSdl {
void Draw(void *data) override;
bool EndDraw() override;
Plip::PlipVideoFormat GetFormat() override;
int GetHeight() override;
int GetWidth() override;
void Render() override;
void Resize(int width, int height) override;
void SetTitle(std::string title) override;
@ -29,6 +31,7 @@ namespace PlipSdl {
private:
void CreateTexture();
bool SelectFormat(uint32_t format);
static uint32_t SelectSdlFormat(Plip::PlipVideoFormat format);
const int m_initWidth = 64;
const int m_initHeight = 64;

15
plip-sdl/SdlEvent.h

@ -1,15 +0,0 @@
/* SdlEvent.h
*
* An SDL2 event handler.
*/
#pragma once
#include "PlipInput.h"
namespace PlipSdl {
class SdlEvent : public Plip::PlipInput {
public:
SdlEvent() = default;
};
}

0
plip-sdl/Timer.h → plip-sdl/Timer/Timer.h

0
plip-sdl/TimerPosix.cpp → plip-sdl/Timer/TimerPosix.cpp

0
plip-sdl/TimerPosix.h → plip-sdl/Timer/TimerPosix.h

0
plip-sdl/TimerSdl.cpp → plip-sdl/Timer/TimerSdl.cpp

0
plip-sdl/TimerSdl.h → plip-sdl/Timer/TimerSdl.h

29
plip-sdl/main.cpp

@ -8,16 +8,31 @@
#include "cxxopts.hpp"
#include "Plip.h"
#include "SdlEvent.h"
#include "SdlWindow.h"
#include "SDL/SdlEvent.h"
#include "SDL/SdlWindow.h"
#ifdef UNIX
#include "TimerPosix.h"
#include "Timer/TimerPosix.h"
#else
#include "TimerSdl.h"
#include "Timer/TimerSdl.h"
#endif
void gameLoop(Plip::Plip *plip, PlipSdl::Timer *timer) {
auto event = new PlipSdl::SdlEvent();
SDL_Event ev;
bool running = true;
while(running) {
while(SDL_PollEvent(&ev)) { // TODO: Temporary event loop. Remove me.
switch(ev.type) {
case SDL_QUIT:
running = false;
break;
}
}
timer->Nanosleep(16666666);
}
}
cxxopts::ParseResult parseCmdLine(int argc, char **argv) {
@ -78,9 +93,10 @@ int main(int argc, char **argv) {
return 1;
}
SDL_Init(0);
auto wnd = new PlipSdl::SdlWindow(opts["scale"].as<int>(), version);
auto event = new PlipSdl::SdlEvent();
auto plip = new Plip::Plip(event, wnd);
auto plip = new Plip::Plip(wnd);
#ifdef UNIX
auto timer = new PlipSdl::TimerPosix();
@ -90,5 +106,6 @@ int main(int argc, char **argv) {
gameLoop(plip, timer);
SDL_Quit();
return 0;
}

Loading…
Cancel
Save