Created
October 4, 2016 13:52
-
-
Save mbabuskov/6f0a2b057c49fcc860e3d28d490fc7dd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef CORE_SCREENSHOT_H_ | |
#define CORE_SCREENSHOT_H_ | |
//------------------------------------------------------------------------------ | |
class Screenshot | |
{ | |
public: | |
int id; // thread ID (only used for loggin and debugging) | |
bool stopflag; // used to "tell" the thread to stop and clean up | |
std::string file; | |
SDL_Surface *surface; | |
Screenshot(int thread, const std::string& filename, SDL_Surface *surf, bool stop = false) | |
:id(thread),stopflag(stop),file(filename),surface(surf) | |
{ | |
} | |
}; | |
//------------------------------------------------------------------------------ | |
static int ScreenshotThread(void *ptr) | |
{ | |
SafeQueue<Screenshot> *q = (SafeQueue<Screenshot> *)ptr; | |
while (true) | |
{ | |
Screenshot s = q->dequeue(); // waits until new screenshot is ready | |
if (s.stopflag) | |
{ | |
// using printf because is sends the whole string at once (unlike std::cout) | |
// http://stackoverflow.com/questions/6374264/is-cout-synchronized-thread-safe | |
printf("Screenshot thread QUIT %d\n", s.id); | |
delete q; // free the queue memory | |
break; | |
} | |
IMG_SavePNG(s.surface, s.file.c_str()); | |
SDL_FreeSurface(s.surface); | |
std::cout << "Screenshot thread " << s.id << " saved: " << s.file.c_str() << std::endl; | |
} | |
return 0; | |
} | |
//------------------------------------------------------------------------------ | |
class ScreenshotManager | |
{ | |
public: | |
bool recording; | |
int screenShotCounter; | |
int width; | |
int height; | |
SDL_Renderer *renderer; | |
std::vector<SafeQueue<Screenshot> *> screenshotQueues; | |
int roundrobin; | |
ScreenshotManager(SDL_Renderer *sdlrend, int w, int h) | |
:recording(false),screenShotCounter(1000000),roundrobin(0), | |
width(w),height(h),renderer(sdlrend) | |
{ | |
for (int i = 0; i < 8; i++) // create 8 threads | |
{ | |
std::stringstream ss; | |
ss << "ScreenshotThread" << i; | |
SafeQueue<Screenshot> *sq = new SafeQueue<Screenshot>; | |
if (!SDL_CreateThread(ScreenshotThread, ss.str().c_str(), (void *)sq)) | |
{ | |
std::cout << "ERROR: SDL_CreateThread failed: " << SDL_GetError() << std::endl; | |
break; | |
} | |
else | |
screenshotQueues.push_back(sq); | |
} | |
} | |
~ScreenshotManager() | |
{ | |
for (int i = 0; i < screenshotQueues.size(); i++) | |
{ | |
Screenshot shot(i, "", 0, true); // true = stop the thread | |
screenshotQueues[i]->enqueue(shot); // tell it to stop and delete the queue | |
} | |
} | |
void screenshot(std::string filename) | |
{ | |
SDL_Surface *sshot = SDL_CreateRGBSurface(0, width, height, | |
32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); | |
if (!sshot) | |
return; | |
SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_ARGB8888, sshot->pixels, sshot->pitch); | |
roundrobin++; | |
if (roundrobin >= screenshotQueues.size()) | |
roundrobin = 0; | |
Screenshot shot(roundrobin, filename, sshot); | |
screenshotQueues[roundrobin]->enqueue(shot); | |
} | |
void update() | |
{ | |
if (!recording || screenshotQueues.size() == 0) | |
return; | |
static bool skipper = true; | |
//skipper = !skipper; // uncomment this line for 30fps | |
if (skipper) | |
{ | |
screenShotCounter++; | |
std::stringstream ss; | |
ss << "shot" << screenShotCounter << ".png"; | |
screenshot(ss.str()); | |
} | |
} | |
int getQueueSize() | |
{ | |
int total = 0; | |
for (std::vector<SafeQueue<Screenshot> *>::iterator it = screenshotQueues.begin(); | |
it != screenshotQueues.end(); ++it) | |
{ | |
total += (*it)->count; | |
} | |
return total; | |
} | |
}; | |
//------------------------------------------------------------------------------ | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment