Hicolor raw dumping
Support hi-color (16bits/channel RGB) raw dumping, since 8 bits per channel are not enough to resolve all the colors.
This commit is contained in:
parent
61f86a8796
commit
228d6a7851
18 changed files with 186 additions and 113 deletions
|
@ -102,7 +102,7 @@ private:
|
|||
* Parameter bgap: Bottom gap.
|
||||
* Parameter fn: Function to call between running lua hooks and actually rendering.
|
||||
*/
|
||||
void render_video_hud(struct screen& target, struct lcscreen& source, uint32_t hscl, uint32_t vscl,
|
||||
template<bool X> void render_video_hud(struct screen<X>& target, struct lcscreen& source, uint32_t hscl, uint32_t vscl,
|
||||
uint32_t roffset, uint32_t goffset, uint32_t boffset, uint32_t lgap, uint32_t tgap, uint32_t rgap,
|
||||
uint32_t bgap, void(*fn)());
|
||||
|
||||
|
|
|
@ -378,11 +378,11 @@ public:
|
|||
*
|
||||
* parameter scr: The render buffer object.
|
||||
*/
|
||||
virtual void on_set_screen(screen& scr);
|
||||
virtual void on_set_screen(screen<false>& scr);
|
||||
/**
|
||||
* Call on_set_screen on all objects.
|
||||
*/
|
||||
static void do_set_screen(screen& scr) throw();
|
||||
static void do_set_screen(screen<false>& scr) throw();
|
||||
/**
|
||||
* Notify that new frame is available.
|
||||
*
|
||||
|
|
|
@ -18,7 +18,7 @@ extern lcscreen screen_corrupt;
|
|||
/**
|
||||
* The main screen to draw on.
|
||||
*/
|
||||
extern screen main_screen;
|
||||
extern screen<false> main_screen;
|
||||
/**
|
||||
* Initialize special screens.
|
||||
*
|
||||
|
|
|
@ -116,11 +116,17 @@ struct lcscreen
|
|||
size_t allocated;
|
||||
};
|
||||
|
||||
template<bool X> struct screenelem {};
|
||||
template<> struct screenelem<false> { typedef uint32_t t; };
|
||||
template<> struct screenelem<true> { typedef uint64_t t; };
|
||||
|
||||
/**
|
||||
* Hicolor modifiable screen.
|
||||
*/
|
||||
template<bool X>
|
||||
struct screen
|
||||
{
|
||||
typedef typename screenelem<X>::t element_t;
|
||||
/**
|
||||
* Creates screen. The screen dimensions are initially 0x0.
|
||||
*/
|
||||
|
@ -139,7 +145,7 @@ struct screen
|
|||
* parameter _height: Height of screen.
|
||||
* parameter _pitch: Distance in bytes between successive scanlines.
|
||||
*/
|
||||
void set(uint32_t* _memory, uint32_t _width, uint32_t _height, uint32_t _pitch) throw();
|
||||
void set(element_t* _memory, uint32_t _width, uint32_t _height, uint32_t _pitch) throw();
|
||||
|
||||
/**
|
||||
* Sets the size of the screen. The memory is freed if screen is reallocated or destroyed.
|
||||
|
@ -174,7 +180,7 @@ struct screen
|
|||
*
|
||||
* parameter row: Number of row (must be less than height).
|
||||
*/
|
||||
uint32_t* rowptr(uint32_t row) throw();
|
||||
element_t* rowptr(uint32_t row) throw();
|
||||
|
||||
/**
|
||||
* Set palette. Also converts the image data.
|
||||
|
@ -188,7 +194,7 @@ struct screen
|
|||
/**
|
||||
* Active palette
|
||||
*/
|
||||
uint32_t* palette;
|
||||
element_t* palette;
|
||||
uint32_t palette_r;
|
||||
uint32_t palette_g;
|
||||
uint32_t palette_b;
|
||||
|
@ -196,7 +202,7 @@ struct screen
|
|||
/**
|
||||
* Backing memory for this screen.
|
||||
*/
|
||||
uint32_t* memory;
|
||||
element_t* memory;
|
||||
|
||||
/**
|
||||
* True if memory is given by user and must not be freed.
|
||||
|
@ -232,19 +238,9 @@ struct screen
|
|||
* Y-coordinate of origin.
|
||||
*/
|
||||
uint32_t originy;
|
||||
|
||||
/**
|
||||
* Returns color value with specified (r,g,b) values (scale 0-255).
|
||||
*
|
||||
* parameter r: Red component.
|
||||
* parameter g: Green component.
|
||||
* parameter b: Blue component.
|
||||
* returns: color element value.
|
||||
*/
|
||||
uint32_t make_color(uint8_t r, uint8_t g, uint8_t b) throw();
|
||||
private:
|
||||
screen(const screen&);
|
||||
screen& operator=(const screen&);
|
||||
screen(const screen<X>&);
|
||||
screen& operator=(const screen<X>&);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -262,7 +258,8 @@ struct render_object
|
|||
*
|
||||
* parameter scr: The screen to draw it on.
|
||||
*/
|
||||
virtual void operator()(struct screen& scr) throw() = 0;
|
||||
virtual void operator()(struct screen<false>& scr) throw() = 0;
|
||||
virtual void operator()(struct screen<true>& scr) throw() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -274,35 +271,33 @@ struct premultiplied_color
|
|||
{
|
||||
uint32_t hi;
|
||||
uint32_t lo;
|
||||
uint64_t hiHI;
|
||||
uint64_t loHI;
|
||||
uint32_t orig;
|
||||
uint16_t origa;
|
||||
uint16_t inv;
|
||||
uint32_t invHI;
|
||||
premultiplied_color(int64_t color) throw()
|
||||
{
|
||||
if(color < 0) {
|
||||
//Transparent.
|
||||
hi = 0;
|
||||
lo = 0;
|
||||
orig = 0;
|
||||
origa = 0;
|
||||
inv = 256;
|
||||
} else {
|
||||
uint32_t c = (color & 0xFFFFFF);
|
||||
uint16_t a = 256 - ((color >> 24) & 0xFF);
|
||||
hi = c & 0xFF00FF;
|
||||
lo = (c & 0x00FF00) >> 8;
|
||||
hi *= a;
|
||||
lo *= a;
|
||||
orig = color & 0xFFFFFF;
|
||||
origa = a;
|
||||
inv = 256 - a;
|
||||
origa = 256 - ((color >> 24) & 0xFF);;
|
||||
inv = 256 - origa;
|
||||
}
|
||||
invHI = 256 * static_cast<uint32_t>(inv);
|
||||
set_palette(16, 8, 0, false);
|
||||
set_palette(32, 16, 0, true);
|
||||
//std::cerr << "Color " << color << " -> hi=" << hi << " lo=" << lo << " inv=" << inv << std::endl;
|
||||
}
|
||||
void set_palette(unsigned rshift, unsigned gshift, unsigned bshift) throw();
|
||||
void set_palette(struct screen& s) throw()
|
||||
void set_palette(unsigned rshift, unsigned gshift, unsigned bshift, bool X) throw();
|
||||
template<bool X> void set_palette(struct screen<X>& s) throw()
|
||||
{
|
||||
set_palette(s.palette_r, s.palette_g, s.palette_b);
|
||||
set_palette(s.palette_r, s.palette_g, s.palette_b, X);
|
||||
}
|
||||
uint32_t blend(uint32_t color) throw()
|
||||
{
|
||||
|
@ -315,6 +310,17 @@ struct premultiplied_color
|
|||
{
|
||||
x = blend(x);
|
||||
}
|
||||
uint64_t blend(uint64_t color) throw()
|
||||
{
|
||||
uint64_t a, b;
|
||||
a = color & 0xFFFF0000FFFFULL;
|
||||
b = (color & 0xFFFF0000FFFF0000ULL) >> 16;
|
||||
return (((a * invHI + hiHI) >> 16) & 0xFFFF0000FFFFULL) | ((b * invHI + loHI) & 0xFFFF0000FFFF0000ULL);
|
||||
}
|
||||
void apply(uint64_t& x) throw()
|
||||
{
|
||||
x = blend(x);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -335,7 +341,7 @@ struct render_queue
|
|||
*
|
||||
* parameter scr: The screen to apply queue to.
|
||||
*/
|
||||
void run(struct screen& scr) throw();
|
||||
template<bool X> void run(struct screen<X>& scr) throw();
|
||||
|
||||
/**
|
||||
* Frees all objects in the queue without applying them.
|
||||
|
@ -393,7 +399,8 @@ std::pair<uint32_t, const uint32_t*> find_glyph(uint32_t codepoint, int32_t x, i
|
|||
* parameter _vdbl: If true, draw text using double height.
|
||||
* throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
void render_text(struct screen& scr, int32_t _x, int32_t _y, const std::string& _text, premultiplied_color _fg,
|
||||
premultiplied_color _bg, bool _hdbl = false, bool _vdbl = false) throw(std::bad_alloc);
|
||||
template<bool X> void render_text(struct screen<X>& scr, int32_t _x, int32_t _y, const std::string& _text,
|
||||
premultiplied_color _fg, premultiplied_color _bg, bool _hdbl = false, bool _vdbl = false)
|
||||
throw(std::bad_alloc);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -104,7 +104,7 @@ adv_dumper::adv_dumper(const std::string& id) throw(std::bad_alloc)
|
|||
dumpers()[d_id] = this;
|
||||
}
|
||||
|
||||
void render_video_hud(struct screen& target, struct lcscreen& source, uint32_t hscl, uint32_t vscl,
|
||||
template<bool X> void render_video_hud(struct screen<X>& target, struct lcscreen& source, uint32_t hscl, uint32_t vscl,
|
||||
uint32_t roffset, uint32_t goffset, uint32_t boffset, uint32_t lgap, uint32_t tgap, uint32_t rgap,
|
||||
uint32_t bgap, void(*fn)())
|
||||
{
|
||||
|
@ -127,3 +127,10 @@ void render_video_hud(struct screen& target, struct lcscreen& source, uint32_t h
|
|||
target.copy_from(source, hscl, vscl);
|
||||
rq.run(target);
|
||||
}
|
||||
|
||||
template void render_video_hud(struct screen<false>& target, struct lcscreen& source, uint32_t hscl, uint32_t vscl,
|
||||
uint32_t roffset, uint32_t goffset, uint32_t boffset, uint32_t lgap, uint32_t tgap, uint32_t rgap,
|
||||
uint32_t bgap, void(*fn)());
|
||||
template void render_video_hud(struct screen<true>& target, struct lcscreen& source, uint32_t hscl, uint32_t vscl,
|
||||
uint32_t roffset, uint32_t goffset, uint32_t boffset, uint32_t lgap, uint32_t tgap, uint32_t rgap,
|
||||
uint32_t bgap, void(*fn)());
|
||||
|
|
|
@ -476,12 +476,12 @@ void information_dispatch::update_dumpers(bool nocalls) throw()
|
|||
}
|
||||
}
|
||||
|
||||
void information_dispatch::on_set_screen(screen& scr)
|
||||
void information_dispatch::on_set_screen(screen<false>& scr)
|
||||
{
|
||||
//Do nothing.
|
||||
}
|
||||
|
||||
void information_dispatch::do_set_screen(screen& scr) throw()
|
||||
void information_dispatch::do_set_screen(screen<false>& scr) throw()
|
||||
{
|
||||
for(auto& i : dispatch()) {
|
||||
START_EH_BLOCK
|
||||
|
|
|
@ -149,7 +149,7 @@ namespace
|
|||
bool last_redraw_no_lua = true;
|
||||
}
|
||||
|
||||
screen main_screen;
|
||||
screen<false> main_screen;
|
||||
|
||||
void take_screenshot(const std::string& file) throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
|
|
|
@ -167,6 +167,28 @@ skip_line:
|
|||
}
|
||||
}
|
||||
|
||||
void premultiplied_color::set_palette(unsigned rshift, unsigned gshift, unsigned bshift, bool X) throw()
|
||||
{
|
||||
if(X) {
|
||||
uint64_t r = ((orig >> 16) & 0xFF) * 257;
|
||||
uint64_t g = ((orig >> 8) & 0xFF) * 257;
|
||||
uint64_t b = (orig & 0xFF) * 257;
|
||||
uint64_t color = (r << rshift) | (g << gshift) | (b << bshift);
|
||||
hiHI = color & 0xFFFF0000FFFFULL;
|
||||
loHI = (color & 0xFFFF0000FFFF0000ULL) >> 16;
|
||||
hiHI *= (static_cast<uint32_t>(origa) * 256);
|
||||
loHI *= (static_cast<uint32_t>(origa) * 256);
|
||||
} else {
|
||||
uint32_t r = (orig >> 16) & 0xFF;
|
||||
uint32_t g = (orig >> 8) & 0xFF;
|
||||
uint32_t b = orig & 0xFF;
|
||||
uint32_t color = (r << rshift) | (g << gshift) | (b << bshift);
|
||||
hi = color & 0xFF00FF;
|
||||
lo = (color & 0xFF00FF00) >> 8;
|
||||
hi *= origa;
|
||||
lo *= origa;
|
||||
}
|
||||
}
|
||||
|
||||
void do_init_font()
|
||||
{
|
||||
|
@ -190,8 +212,8 @@ render_object::~render_object() throw()
|
|||
{
|
||||
}
|
||||
|
||||
void render_text(struct screen& scr, int32_t x, int32_t y, const std::string& text, premultiplied_color fg,
|
||||
premultiplied_color bg, bool hdbl, bool vdbl) throw(std::bad_alloc)
|
||||
template<bool X> void render_text(struct screen<X>& scr, int32_t x, int32_t y, const std::string& text,
|
||||
premultiplied_color fg, premultiplied_color bg, bool hdbl, bool vdbl) throw(std::bad_alloc)
|
||||
{
|
||||
int32_t orig_x = x;
|
||||
uint32_t unicode_code = 0;
|
||||
|
@ -254,14 +276,14 @@ void render_text(struct screen& scr, int32_t x, int32_t y, const std::string& te
|
|||
if(p.second == NULL) {
|
||||
//Blank glyph.
|
||||
for(uint32_t j = 0; j < dh; j++) {
|
||||
uint32_t* base = scr.rowptr(cy + j) + cx;
|
||||
typename screen<X>::element_t* base = scr.rowptr(cy + j) + cx;
|
||||
for(uint32_t i = 0; i < dw; i++)
|
||||
bg.apply(base[i]);
|
||||
}
|
||||
} else {
|
||||
for(uint32_t j = 0; j < dh; j++) {
|
||||
uint32_t dataword = p.second[(dy + j) >> rshift];
|
||||
uint32_t* base = scr.rowptr(cy + j) + cx;
|
||||
typename screen<X>::element_t* base = scr.rowptr(cy + j) + cx;
|
||||
uint32_t rbit = (~((dy + j) >> yshift << rishift) & 31) - (dx >> xshift);
|
||||
if(hdbl) {
|
||||
for(uint32_t i = 0; i < dw; i++)
|
||||
|
@ -288,7 +310,7 @@ void render_queue::add(struct render_object& obj) throw(std::bad_alloc)
|
|||
q.push_back(&obj);
|
||||
}
|
||||
|
||||
void render_queue::run(struct screen& scr) throw()
|
||||
template<bool X> void render_queue::run(struct screen<X>& scr) throw()
|
||||
{
|
||||
for(auto i : q) {
|
||||
try {
|
||||
|
@ -310,14 +332,6 @@ render_queue::~render_queue() throw()
|
|||
clear();
|
||||
}
|
||||
|
||||
uint32_t screen::make_color(uint8_t r, uint8_t g, uint8_t b) throw()
|
||||
{
|
||||
uint32_t _r = r;
|
||||
uint32_t _g = g;
|
||||
uint32_t _b = b;
|
||||
return (_r << 16) + (_g << 8) + _b;
|
||||
}
|
||||
|
||||
lcscreen::lcscreen(const uint32_t* mem, bool hires, bool interlace, bool overscan, bool region) throw()
|
||||
{
|
||||
uint32_t dataoffset = 0;
|
||||
|
@ -457,12 +471,12 @@ void lcscreen::save_png(const std::string& file) throw(std::bad_alloc, std::runt
|
|||
}
|
||||
}
|
||||
|
||||
void screen::copy_from(lcscreen& scr, uint32_t hscale, uint32_t vscale) throw()
|
||||
template<bool X> void screen<X>::copy_from(lcscreen& scr, uint32_t hscale, uint32_t vscale) throw()
|
||||
{
|
||||
if(width < originx || height < originy) {
|
||||
//Just clear the screen.
|
||||
for(uint32_t y = 0; y < height; y++)
|
||||
memset(rowptr(y), 0, 4 * width);
|
||||
memset(rowptr(y), 0, sizeof(typename screen<X>::element_t) * width);
|
||||
return;
|
||||
}
|
||||
uint32_t copyable_width = 0, copyable_height = 0;
|
||||
|
@ -473,22 +487,23 @@ void screen::copy_from(lcscreen& scr, uint32_t hscale, uint32_t vscale) throw()
|
|||
copyable_width = (copyable_width > scr.width) ? scr.width : copyable_width;
|
||||
copyable_height = (copyable_height > scr.height) ? scr.height : copyable_height;
|
||||
for(uint32_t y = 0; y < height; y++)
|
||||
memset(rowptr(y), 0, 4 * width);
|
||||
memset(rowptr(y), 0, sizeof(typename screen<X>::element_t) * width);
|
||||
for(uint32_t y = 0; y < copyable_height; y++) {
|
||||
uint32_t line = y * vscale + originy;
|
||||
uint32_t* ptr = rowptr(line) + originx;
|
||||
typename screen<X>::element_t* ptr = rowptr(line) + originx;
|
||||
const uint32_t* sbase = scr.memory + y * scr.pitch;
|
||||
for(uint32_t x = 0; x < copyable_width; x++) {
|
||||
uint32_t c = palette[sbase[x] & 0x7FFFF];
|
||||
typename screen<X>::element_t c = palette[sbase[x] & 0x7FFFF];
|
||||
for(uint32_t i = 0; i < hscale; i++)
|
||||
*(ptr++) = c;
|
||||
}
|
||||
for(uint32_t j = 1; j < vscale; j++)
|
||||
memcpy(rowptr(line + j) + originx, rowptr(line) + originx, 4 * hscale * copyable_width);
|
||||
memcpy(rowptr(line + j) + originx, rowptr(line) + originx,
|
||||
sizeof(typename screen<X>::element_t) * hscale * copyable_width);
|
||||
}
|
||||
}
|
||||
|
||||
void screen::reallocate(uint32_t _width, uint32_t _height, bool upside_down) throw(std::bad_alloc)
|
||||
template<bool X> void screen<X>::reallocate(uint32_t _width, uint32_t _height, bool upside_down) throw(std::bad_alloc)
|
||||
{
|
||||
if(_width == width && _height == height)
|
||||
return;
|
||||
|
@ -501,10 +516,10 @@ void screen::reallocate(uint32_t _width, uint32_t _height, bool upside_down) thr
|
|||
flipped = upside_down;
|
||||
return;
|
||||
}
|
||||
uint32_t* newmem = new uint32_t[_width * _height];
|
||||
typename screen<X>::element_t* newmem = new typename screen<X>::element_t[_width * _height];
|
||||
width = _width;
|
||||
height = _height;
|
||||
pitch = 4 * _width;
|
||||
pitch = sizeof(typename screen<X>::element_t) * _width;
|
||||
if(memory && !user_memory)
|
||||
delete[] memory;
|
||||
memory = newmem;
|
||||
|
@ -512,7 +527,8 @@ void screen::reallocate(uint32_t _width, uint32_t _height, bool upside_down) thr
|
|||
flipped = upside_down;
|
||||
}
|
||||
|
||||
void screen::set(uint32_t* _memory, uint32_t _width, uint32_t _height, uint32_t _pitch) throw()
|
||||
template<bool X> void screen<X>::set(typename screen<X>::element_t* _memory, uint32_t _width, uint32_t _height,
|
||||
uint32_t _pitch) throw()
|
||||
{
|
||||
if(memory && !user_memory)
|
||||
delete[] memory;
|
||||
|
@ -524,21 +540,20 @@ void screen::set(uint32_t* _memory, uint32_t _width, uint32_t _height, uint32_t
|
|||
flipped = false;
|
||||
}
|
||||
|
||||
void screen::set_origin(uint32_t _originx, uint32_t _originy) throw()
|
||||
template<bool X> void screen<X>::set_origin(uint32_t _originx, uint32_t _originy) throw()
|
||||
{
|
||||
originx = _originx;
|
||||
originy = _originy;
|
||||
}
|
||||
|
||||
|
||||
uint32_t* screen::rowptr(uint32_t row) throw()
|
||||
template<bool X> typename screen<X>::element_t* screen<X>::rowptr(uint32_t row) throw()
|
||||
{
|
||||
if(flipped)
|
||||
row = height - row - 1;
|
||||
return reinterpret_cast<uint32_t*>(reinterpret_cast<uint8_t*>(memory) + row * pitch);
|
||||
return reinterpret_cast<typename screen<X>::element_t*>(reinterpret_cast<uint8_t*>(memory) + row * pitch);
|
||||
}
|
||||
|
||||
screen::screen() throw()
|
||||
template<bool X> screen<X>::screen() throw()
|
||||
{
|
||||
memory = NULL;
|
||||
width = height = originx = originy = pitch = 0;
|
||||
|
@ -548,7 +563,7 @@ screen::screen() throw()
|
|||
set_palette(16, 8, 0);
|
||||
}
|
||||
|
||||
screen::~screen() throw()
|
||||
template<bool X> screen<X>::~screen() throw()
|
||||
{
|
||||
if(memory && !user_memory)
|
||||
delete[] memory;
|
||||
|
@ -577,26 +592,26 @@ void clip_range(uint32_t origin, uint32_t size, int32_t base, int32_t& minc, int
|
|||
}
|
||||
}
|
||||
|
||||
void screen::set_palette(uint32_t r, uint32_t g, uint32_t b)
|
||||
template<bool X> void screen<X>::set_palette(uint32_t r, uint32_t g, uint32_t b)
|
||||
{
|
||||
if(!palette)
|
||||
palette = new uint32_t[0x80000];
|
||||
palette = new element_t[0x80000];
|
||||
else if(r == palette_r && g == palette_g && b == palette_b)
|
||||
return;
|
||||
for(size_t i = 0; i < static_cast<size_t>(width) * height; i++) {
|
||||
uint32_t word = memory[i];
|
||||
uint32_t R = (word >> palette_r) & 0xFF;
|
||||
uint32_t G = (word >> palette_g) & 0xFF;
|
||||
uint32_t B = (word >> palette_b) & 0xFF;
|
||||
uint32_t R = (word >> palette_r) & (X ? 0xFFFF : 0xFF);
|
||||
uint32_t G = (word >> palette_g) & (X ? 0xFFFF : 0xFF);
|
||||
uint32_t B = (word >> palette_b) & (X ? 0xFFFF : 0xFF);
|
||||
memory[i] = (R << r) | (G << g) | (B << b);
|
||||
}
|
||||
for(unsigned i = 0; i < 0x80000; i++) {
|
||||
unsigned l = 1 + ((i >> 15) & 0xF);
|
||||
unsigned R = (i >> 0) & 0x1F;
|
||||
unsigned G = (i >> 5) & 0x1F;
|
||||
unsigned B = (i >> 10) & 0x1F;
|
||||
element_t R = (i >> 0) & 0x1F;
|
||||
element_t G = (i >> 5) & 0x1F;
|
||||
element_t B = (i >> 10) & 0x1F;
|
||||
double _l = static_cast<double>(l);
|
||||
double m = 255.0 / 496.0;
|
||||
double m = (X ? 65535.0 : 255.0) / 496.0;
|
||||
R = floor(m * R * _l + 0.5);
|
||||
G = floor(m * G * _l + 0.5);
|
||||
B = floor(m * B * _l + 0.5);
|
||||
|
@ -607,14 +622,12 @@ void screen::set_palette(uint32_t r, uint32_t g, uint32_t b)
|
|||
palette_b = b;
|
||||
}
|
||||
|
||||
void premultiplied_color::set_palette(unsigned rshift, unsigned gshift, unsigned bshift) throw()
|
||||
{
|
||||
uint32_t r = (orig >> 16) & 0xFF;
|
||||
uint32_t g = (orig >> 8) & 0xFF;
|
||||
uint32_t b = orig & 0xFF;
|
||||
uint32_t color = (r << rshift) | (g << gshift) | (b << bshift);
|
||||
hi = color & 0xFF00FF;
|
||||
lo = (color & 0xFF00FF00) >> 8;
|
||||
hi *= origa;
|
||||
lo *= origa;
|
||||
}
|
||||
|
||||
template struct screen<false>;
|
||||
template struct screen<true>;
|
||||
template void render_queue::run(screen<false>&);
|
||||
template void render_queue::run(screen<true>&);
|
||||
template void render_text(struct screen<false>& scr, int32_t x, int32_t y, const std::string& text,
|
||||
premultiplied_color fg, premultiplied_color bg, bool hdbl, bool vdbl) throw(std::bad_alloc);
|
||||
template void render_text(struct screen<true>& scr, int32_t x, int32_t y, const std::string& text,
|
||||
premultiplied_color fg, premultiplied_color bg, bool hdbl, bool vdbl) throw(std::bad_alloc);
|
||||
|
|
|
@ -509,7 +509,7 @@ void platform::run_queues() throw()
|
|||
namespace
|
||||
{
|
||||
mutex* _msgbuf_lock;
|
||||
screen* our_screen;
|
||||
screen<false>* our_screen;
|
||||
|
||||
void trigger_repaint()
|
||||
{
|
||||
|
@ -519,14 +519,14 @@ namespace
|
|||
struct painter_listener : public information_dispatch
|
||||
{
|
||||
painter_listener();
|
||||
void on_set_screen(screen& scr);
|
||||
void on_set_screen(screen<false>& scr);
|
||||
void on_screen_update();
|
||||
void on_status_update();
|
||||
} x;
|
||||
|
||||
painter_listener::painter_listener() : information_dispatch("painter-listener") {}
|
||||
|
||||
void painter_listener::on_set_screen(screen& scr)
|
||||
void painter_listener::on_set_screen(screen<false>& scr)
|
||||
{
|
||||
our_screen = &scr;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace
|
|||
(_radius - _thickness);
|
||||
}
|
||||
~render_object_circle() throw() {}
|
||||
void operator()(struct screen& scr) throw()
|
||||
template<bool X> void op(struct screen<X>& scr) throw()
|
||||
{
|
||||
outline.set_palette(scr);
|
||||
fill.set_palette(scr);
|
||||
|
@ -30,7 +30,7 @@ namespace
|
|||
clip_range(scr.originy, scr.height, y, ymin, ymax);
|
||||
for(int32_t r = ymin; r < ymax; r++) {
|
||||
uint64_t pd2 = static_cast<int64_t>(r) * r;
|
||||
uint32_t* rptr = scr.rowptr(y + r + scr.originy);
|
||||
typename screen<X>::element_t* rptr = scr.rowptr(y + r + scr.originy);
|
||||
size_t eptr = x + xmin + scr.originx;
|
||||
for(int32_t c = xmin; c < xmax; c++, eptr++) {
|
||||
uint64_t fd2 = pd2 + static_cast<int64_t>(c) * c;
|
||||
|
@ -43,6 +43,8 @@ namespace
|
|||
}
|
||||
}
|
||||
}
|
||||
void operator()(struct screen<true>& scr) throw() { op(scr); }
|
||||
void operator()(struct screen<false>& scr) throw() { op(scr); }
|
||||
private:
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace
|
|||
render_object_crosshair(int32_t _x, int32_t _y, premultiplied_color _color, uint32_t _length) throw()
|
||||
: x(_x), y(_y), color(_color), length(_length) {}
|
||||
~render_object_crosshair() throw() {}
|
||||
void operator()(struct screen& scr) throw()
|
||||
template<bool X> void op(struct screen<X>& scr) throw()
|
||||
{
|
||||
color.set_palette(scr);
|
||||
int32_t xmin = -static_cast<int32_t>(length);
|
||||
|
@ -24,6 +24,8 @@ namespace
|
|||
for(int32_t r = xmin; r < xmax; r++)
|
||||
color.apply(scr.rowptr(y + scr.originy)[x + r + scr.originx]);
|
||||
}
|
||||
void operator()(struct screen<true>& scr) throw() { op(scr); }
|
||||
void operator()(struct screen<false>& scr) throw() { op(scr); }
|
||||
private:
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace
|
|||
throw()
|
||||
: x1(_x1), y1(_y1), x2(_x2), y2(_y2), color(_color) {}
|
||||
~render_object_line() throw() {}
|
||||
void operator()(struct screen& scr) throw()
|
||||
template<bool X> void op(struct screen<X>& scr) throw()
|
||||
{
|
||||
color.set_palette(scr);
|
||||
int32_t xdiff = x2 - x1;
|
||||
|
@ -72,6 +72,8 @@ nodraw2:
|
|||
}
|
||||
}
|
||||
}
|
||||
void operator()(struct screen<true>& scr) throw() { op(scr); }
|
||||
void operator()(struct screen<false>& scr) throw() { op(scr); }
|
||||
private:
|
||||
int32_t x1;
|
||||
int32_t y1;
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace
|
|||
render_object_pixel(int32_t _x, int32_t _y, premultiplied_color _color) throw()
|
||||
: x(_x), y(_y), color(_color) {}
|
||||
~render_object_pixel() throw() {}
|
||||
void operator()(struct screen& scr) throw()
|
||||
template<bool X> void op(struct screen<X>& scr) throw()
|
||||
{
|
||||
color.set_palette(scr);
|
||||
int32_t _x = x + scr.originx;
|
||||
|
@ -19,6 +19,8 @@ namespace
|
|||
return;
|
||||
color.apply(scr.rowptr(_y)[_x]);
|
||||
}
|
||||
void operator()(struct screen<true>& scr) throw() { op(scr); }
|
||||
void operator()(struct screen<false>& scr) throw() { op(scr); }
|
||||
private:
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace
|
|||
: x(_x), y(_y), width(_width), height(_height), outline(_outline), fill(_fill),
|
||||
thickness(_thickness) {}
|
||||
~render_object_rectangle() throw() {}
|
||||
void operator()(struct screen& scr) throw()
|
||||
template<bool X> void op(struct screen<X>& scr) throw()
|
||||
{
|
||||
outline.set_palette(scr);
|
||||
fill.set_palette(scr);
|
||||
|
@ -21,7 +21,7 @@ namespace
|
|||
clip_range(scr.originx, scr.width, x, xmin, xmax);
|
||||
clip_range(scr.originy, scr.height, y, ymin, ymax);
|
||||
for(int32_t r = ymin; r < ymax; r++) {
|
||||
uint32_t* rptr = scr.rowptr(y + r + scr.originy);
|
||||
typename screen<X>::element_t* rptr = scr.rowptr(y + r + scr.originy);
|
||||
size_t eptr = x + xmin + scr.originx;
|
||||
for(int32_t c = xmin; c < xmax; c++, eptr++)
|
||||
if(r < thickness || c < thickness || r >= height - thickness ||
|
||||
|
@ -31,6 +31,8 @@ namespace
|
|||
fill.apply(rptr[eptr]);
|
||||
}
|
||||
}
|
||||
void operator()(struct screen<true>& scr) throw() { op(scr); }
|
||||
void operator()(struct screen<false>& scr) throw() { op(scr); }
|
||||
private:
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
|
|
|
@ -9,12 +9,14 @@ namespace
|
|||
premultiplied_color _bg, bool _hdbl = false, bool _vdbl = false) throw()
|
||||
: x(_x), y(_y), text(_text), fg(_fg), bg(_bg), hdbl(_hdbl), vdbl(_vdbl) {}
|
||||
~render_object_text() throw() {}
|
||||
void operator()(struct screen& scr) throw()
|
||||
template<bool X> void op(struct screen<X>& scr) throw()
|
||||
{
|
||||
fg.set_palette(scr);
|
||||
bg.set_palette(scr);
|
||||
render_text(scr, x, y, text, fg, bg, hdbl, vdbl);
|
||||
}
|
||||
void operator()(struct screen<true>& scr) throw() { op(scr); }
|
||||
void operator()(struct screen<false>& scr) throw() { op(scr); }
|
||||
private:
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
|
|
|
@ -257,7 +257,7 @@ namespace
|
|||
avi_worker* worker;
|
||||
private:
|
||||
sox_dumper* soxdumper;
|
||||
screen dscr;
|
||||
screen<false> dscr;
|
||||
unsigned dcounter;
|
||||
bool have_dumped_frame;
|
||||
std::pair<uint32_t, uint32_t> soundrate;
|
||||
|
|
|
@ -159,7 +159,7 @@ namespace
|
|||
return ret;
|
||||
}
|
||||
|
||||
screen dscr;
|
||||
screen<false> dscr;
|
||||
unsigned dcounter;
|
||||
bool have_dumped_frame;
|
||||
uint64_t audio_w;
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace
|
|||
class raw_avsnoop : public information_dispatch
|
||||
{
|
||||
public:
|
||||
raw_avsnoop(const std::string& prefix) throw(std::bad_alloc)
|
||||
raw_avsnoop(const std::string& prefix, bool _swap, bool _bits64) throw(std::bad_alloc)
|
||||
: information_dispatch("dump-raw")
|
||||
{
|
||||
enable_send_sound();
|
||||
|
@ -23,6 +23,8 @@ namespace
|
|||
if(!*video || !*audio)
|
||||
throw std::runtime_error("Can't open output files");
|
||||
have_dumped_frame = false;
|
||||
swap = _swap;
|
||||
bits64 = _bits64;
|
||||
}
|
||||
|
||||
~raw_avsnoop() throw()
|
||||
|
@ -35,15 +37,27 @@ namespace
|
|||
{
|
||||
if(!video)
|
||||
return;
|
||||
unsigned magic = 0x18100800U;
|
||||
unsigned r = (reinterpret_cast<unsigned char*>(&magic))[2];
|
||||
unsigned magic;
|
||||
if(bits64)
|
||||
magic = 0x30201000U;
|
||||
else
|
||||
magic = 0x18100800U;
|
||||
unsigned r = (reinterpret_cast<unsigned char*>(&magic))[swap ? 2 : 0];
|
||||
unsigned g = (reinterpret_cast<unsigned char*>(&magic))[1];
|
||||
unsigned b = (reinterpret_cast<unsigned char*>(&magic))[0];
|
||||
unsigned b = (reinterpret_cast<unsigned char*>(&magic))[swap ? 0 : 2];
|
||||
uint32_t hscl = (_frame.width < 400) ? 2 : 1;
|
||||
uint32_t vscl = (_frame.height < 400) ? 2 : 1;
|
||||
if(bits64) {
|
||||
render_video_hud(dscr2, _frame, hscl, vscl, r, g, b, 0, 0, 0, 0, NULL);
|
||||
for(size_t i = 0; i < dscr2.height; i++)
|
||||
video->write(reinterpret_cast<char*>(dscr2.rowptr(i)), 8 * dscr2.width);
|
||||
} else {
|
||||
render_video_hud(dscr, _frame, hscl, vscl, r, g, b, 0, 0, 0, 0, NULL);
|
||||
for(size_t i = 0; i < dscr.height; i++)
|
||||
video->write(reinterpret_cast<char*>(dscr.rowptr(i)), 4 * dscr.width);
|
||||
}
|
||||
if(!*video)
|
||||
messages << "Video write error" << std::endl;
|
||||
have_dumped_frame = true;
|
||||
}
|
||||
|
||||
|
@ -73,7 +87,10 @@ namespace
|
|||
std::ofstream* audio;
|
||||
std::ofstream* video;
|
||||
bool have_dumped_frame;
|
||||
struct screen dscr;
|
||||
struct screen<false> dscr;
|
||||
struct screen<true> dscr2;
|
||||
bool swap;
|
||||
bool bits64;
|
||||
};
|
||||
|
||||
raw_avsnoop* vid_dumper;
|
||||
|
@ -86,6 +103,10 @@ namespace
|
|||
std::set<std::string> list_submodes() throw(std::bad_alloc)
|
||||
{
|
||||
std::set<std::string> x;
|
||||
x.insert("rgb32");
|
||||
x.insert("rgb64");
|
||||
x.insert("bgr32");
|
||||
x.insert("bgr64");
|
||||
return x;
|
||||
}
|
||||
|
||||
|
@ -101,7 +122,14 @@ namespace
|
|||
|
||||
std::string modename(const std::string& mode) throw(std::bad_alloc)
|
||||
{
|
||||
return "";
|
||||
if(mode == "rgb32")
|
||||
return "RGB 32-bit";
|
||||
if(mode == "bgr32")
|
||||
return "BGR 32-bit";
|
||||
if(mode == "rgb64")
|
||||
return "RGB 64-bit";
|
||||
if(mode == "bgr64")
|
||||
return "BGR 64-bit";
|
||||
}
|
||||
|
||||
bool busy()
|
||||
|
@ -112,12 +140,18 @@ namespace
|
|||
void start(const std::string& mode, const std::string& prefix) throw(std::bad_alloc,
|
||||
std::runtime_error)
|
||||
{
|
||||
bool bits64 = false;
|
||||
bool swap = false;
|
||||
if(mode == "bgr32" || mode == "bgr64")
|
||||
swap = true;
|
||||
if(mode == "rgb64" || mode == "bgr64")
|
||||
bits64 = true;
|
||||
if(prefix == "")
|
||||
throw std::runtime_error("Expected prefix");
|
||||
if(vid_dumper)
|
||||
throw std::runtime_error("RAW dumping already in progress");
|
||||
try {
|
||||
vid_dumper = new raw_avsnoop(prefix);
|
||||
vid_dumper = new raw_avsnoop(prefix, swap, bits64);
|
||||
} catch(std::bad_alloc& e) {
|
||||
throw;
|
||||
} catch(std::exception& e) {
|
||||
|
|
Loading…
Add table
Reference in a new issue