pingxelflut/screen_sdl.cpp
2017-05-27 20:28:50 +02:00

167 lines
4.7 KiB
C++

#include "screen_sdl.hpp"
#include "types.hpp"
#include <chrono>
#include <iostream>
#include <pthread.h>
#include <cstdbool>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <unistd.h>
#ifndef SAVE_PATH
#define SAVE_PATH "/tmp"
#endif
#ifndef SCREEN_WIDTH
#define SCREEN_WIDTH 800
#endif
#ifndef SCREEN_HEIGHT
#define SCREEN_HEIGHT 600
#endif
namespace screen {
screen_SDL::screen_SDL() {
startTime = time(0);
init_SDL();
update_thread = std::thread([this]() {
while (1) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
updateDisplay();
}
});
pthread_setname_np(update_thread.native_handle(), "update_screen");
}
screen_SDL::~screen_SDL(void) {
SDL_FreeSurface(surf1);
SDL_Quit();
}
void screen_SDL::surfDump(unsigned int n) {
while (n % 4)
n++;
printf("Surface dump first %d bytes:", n);
for (unsigned int i = 0; i < n; i += 4)
printf(" 0x%02x%02x%02x%02x", ((unsigned char *)surf1->pixels)[i],
((unsigned char *)surf1->pixels)[i + 1],
((unsigned char *)surf1->pixels)[i + 2],
((unsigned char *)surf1->pixels)[i + 3]);
printf("\n");
}
void screen_SDL::dumpFormat(void) {
printf("BitsPerPixel: %d\n", surf1->format->BitsPerPixel);
printf("BytesPerPixel: %d\n", surf1->format->BytesPerPixel);
printf("[RGBA]loss: %d %d %d %d\n", surf1->format->Rloss,
surf1->format->Gloss, surf1->format->Bloss, surf1->format->Aloss);
printf("[RGBA]shift: 0x%02x 0x%02x 0x%02x 0x%02x\n", surf1->format->Rshift,
surf1->format->Gshift, surf1->format->Bshift, surf1->format->Ashift);
printf("[RGBA]mask: 0x%08x 0x%08x 0x%08x 0x%08x\n", surf1->format->Rmask,
surf1->format->Gmask, surf1->format->Bmask, surf1->format->Amask);
// printf("colorkey: %d\n", surf1->format->colorkey);
// printf("alpha: %d\n", surf1->format->alpha);
}
void setPixel(SDL_Surface *surf, unsigned short x, unsigned short y,
unsigned char r, unsigned char g, unsigned char b) {
uint32_t *pixel = reinterpret_cast<uint32_t *>(
(unsigned char *)surf->pixels +
(surf->pitch * y + x * (size_t)surf->format->BytesPerPixel));
*pixel = (r << (surf->format->Rshift) & surf->format->Rmask) |
(g << (surf->format->Gshift) & surf->format->Gmask) |
(b << (surf->format->Bshift) & surf->format->Bmask);
}
int saveBMP(SDL_Surface *surf, time_t time) {
char filename[sizeof SAVE_PATH "/1495813229.bmp"];
sprintf(filename, SAVE_PATH "/%010d.bmp", (unsigned int)time);
if (access(filename, F_OK) != -1) {
}
SDL_SaveBMP(surf, filename);
}
void screen_SDL::init_SDL() {
printf("width %d\n", SCREEN_WIDTH);
if (SDL_Init(SDL_INIT_VIDEO)) {
printf("Couldn't initialize SDL: %s\n", SDL_GetError());
}
surf1 = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 0, SDL_SWSURFACE | SDL_FULLSCREEN);
if (!surf1) {
printf("Couldn't initialize surface: %s\n", SDL_GetError());
}
char buf[16];
if (!SDL_VideoDriverName(buf, 16)) {
printf("Couldn't get video driver name\n");
}
printf("SDL_VideoDriver: %s\n", buf);
printf("Filling surf1 and updating. Display should turn blue now\n");
SDL_FillRect(surf1, 0, SDL_MapRGB(surf1->format, 0, 0, 0xff));
printf("PixelFormat of surf1:\n");
dumpFormat();
surfDump(16);
SDL_UpdateRect(surf1, 0, 0, 0, 0);
usleep(300000);
printf("Filling surf1 and updating. Display should turn black now\n");
SDL_FillRect(surf1, 0, SDL_MapRGB(surf1->format, 0, 0, 0x00));
SDL_UpdateRect(surf1, 0, 0, 0, 0);
usleep(300000);
SDL_ShowCursor(SDL_DISABLE);
}
void screen_SDL::consume_pixel(const types::pixel &input) {
// std::cout << "x: " << input.x << " y:" << input.y << std::endl;
if ((input.x >= SCREEN_WIDTH) || (input.y >= SCREEN_HEIGHT))
{
return;
}
setPixel(surf1, input.x, input.y, input.red, input.green, input.blue);
}
void screen_SDL::updateDisplay(void) {
time_t newTime = startTime;
SDL_Event event;
SDL_UpdateRect(surf1, 0, 0, 0, 0);
// usleep(10000);
frames++;
newTime = time(0);
if (currentTime != newTime) {
saveBMP(surf1, newTime);
float fps = (float)frames / (newTime - startTime);
fflush(stdout);
currentTime = newTime;
}
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
printf("Quit.\n");
break;
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_q:
break;
// case SDLK_f:
// uint32_t flags = SDL_GetWindowFlags(window);
// SDL_SetWindowFullscreen(window,
// (flags & SDL_WINDOW_FULLSCREEN) ? 0 :
// SDL_WINDOW_FULLSCREEN_DESKTOP);
// printf("Toggled Fullscreen\n");
default:
printf("Unhandled SDL_Key_Event\n");
}
default:
printf("Unhandled SDL_Event\n");
}
}
}
}