#ifndef TBB_examples_video_H
#define TBB_examples_video_H
#include <cassert>
#include <cstddef>
#if _MSC_VER
#include <stddef.h>
#else
#include <stdint.h>
#endif
#if _WIN32 || _WIN64
#include <windows.h>
#else
#include <unistd.h>
#endif
typedef unsigned int color_t;
typedef unsigned char colorcomp_t;
typedef signed char depth_t;
class drawing_memory {
uintptr_t my_address;
public:
depth_t pixel_depth;
int sizex, sizey;
inline char *get_address() const {
return reinterpret_cast<char *>(my_address);
}
inline int get_size() const {
return ((pixel_depth > 16) ? 4 : 2) * sizex * sizey;
}
inline void set_address(char *mem) {
my_address = reinterpret_cast<uintptr_t>(mem);
}
friend class drawing_area;
friend class video;
};
class video {
depth_t depth, red_shift, green_shift, blue_shift;
color_t red_mask, green_mask, blue_mask;
friend class drawing_area;
public:
video();
~video();
const char *title;
bool calc_fps;
bool threaded;
bool running;
bool updating;
bool init_window(int sizex, int sizey);
bool init_console();
void terminate();
void main_loop();
bool next_frame();
void show_title();
inline color_t get_color(colorcomp_t red, colorcomp_t green, colorcomp_t blue) const;
inline drawing_memory get_drawing_memory() const;
static const int esc_key = 27;
virtual void on_mouse(int x, int y, int key) {}
virtual void on_key(int key) {}
virtual void on_process() {
while (next_frame())
;
}
#ifdef _WINDOWS
static HINSTANCE win_hInstance;
static int win_iCmdShow;
void win_set_class(WNDCLASSEX &);
void win_load_accelerators(int idc);
#endif
};
class drawing_area {
const std::size_t base_index, max_index, index_stride;
const depth_t pixel_depth;
unsigned int *const ptr32;
std::size_t index;
public:
const int start_x, start_y, size_x, size_y;
drawing_area(int x, int y, int sizex, int sizey);
inline drawing_area(int x, int y, int sizex, int sizey, const drawing_memory &dmem);
inline ~drawing_area();
void update();
inline void set_pos(int local_x, int local_y);
inline void put_pixel(color_t color);
void set_pixel(int localx, int localy, color_t color) {
set_pos(localx, localy);
put_pixel(color);
}
};
extern int g_sizex;
extern int g_sizey;
extern unsigned int *g_pImg;
inline drawing_memory video::get_drawing_memory() const {
drawing_memory dmem;
dmem.pixel_depth = depth;
dmem.my_address = reinterpret_cast<uintptr_t>(g_pImg);
dmem.sizex = g_sizex;
dmem.sizey = g_sizey;
return dmem;
}
inline color_t video::get_color(colorcomp_t red, colorcomp_t green, colorcomp_t blue) const {
if (red_shift == 16) return (red << 16) | (green << 8) | blue;
else if (depth >= 24)
return
#if __ANDROID__
0xFF000000 |
#endif
(red << red_shift) | (green << green_shift) | (blue << blue_shift);
else if (depth > 0) {
depth_t bs = blue_shift, rs = red_shift;
if (blue_shift < 0)
blue >>= -bs, bs = 0;
else
red >>= -rs, rs = 0;
return ((red << rs) & red_mask) | ((green << green_shift) & green_mask) |
((blue << bs) & blue_mask);
}
else { unsigned y, u, v;
y = red * 77 + green * 150 + blue * 29; u = (2048 + (blue << 3) - (y >> 5)) >> 4; v = (2048 + (red << 3) - (y >> 5)) >> 4;
y = y >> 8;
return u | (y << 8) | (v << 16) | (y << 24);
}
}
inline drawing_area::drawing_area(int x, int y, int sizex, int sizey, const drawing_memory &dmem)
: base_index(y * dmem.sizex + x),
max_index(dmem.sizex * dmem.sizey),
index_stride(dmem.sizex),
pixel_depth(dmem.pixel_depth),
ptr32(reinterpret_cast<unsigned int *>(dmem.my_address)),
start_x(x),
start_y(y),
size_x(sizex),
size_y(sizey) {
assert(x < dmem.sizex);
assert(y < dmem.sizey);
assert(x + sizex <= dmem.sizex);
assert(y + sizey <= dmem.sizey);
index = base_index; }
inline void drawing_area::set_pos(int local_x, int local_y) {
index = base_index + local_x + local_y * index_stride;
}
inline void drawing_area::put_pixel(color_t color) {
assert(index < max_index);
if (pixel_depth > 16)
ptr32[index++] = color;
else if (pixel_depth > 0)
((unsigned short *)ptr32)[index++] = (unsigned short)color;
else { if (index & 1)
color >>= 16;
((unsigned short *)ptr32)[index++] = (unsigned short)color;
}
}
inline drawing_area::~drawing_area() {}
#if defined(_WINDOWS) && (defined(VIDEO_WINMAIN) || defined(VIDEO_WINMAIN_ARGS))
#include <cstdlib>
#ifdef VIDEO_WINMAIN_ARGS
int main(int, char *[]);
#else
int main();
#endif
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR szCmdLine, int iCmdShow) {
video::win_hInstance = hInstance;
video::win_iCmdShow = iCmdShow;
#ifdef VIDEO_WINMAIN_ARGS
return main(__argc, __argv);
#else
return main();
#endif
}
#endif
#endif