Switch internally to 16-bit graphics instead of 32-bit
This commit is contained in:
parent
9c3cdb57c5
commit
99468dc616
11 changed files with 313 additions and 294 deletions
|
@ -488,6 +488,8 @@ namespace
|
|||
std::list<std::string>::iterator commandhistory_itr;
|
||||
screen* current_screen;
|
||||
SDL_Surface* hwsurf;
|
||||
SDL_Surface* swsurf;
|
||||
std::pair<uint32_t, uint32_t> current_windowsize;
|
||||
bool pause_active;
|
||||
uint64_t last_ui_update;
|
||||
bool screen_is_dirty;
|
||||
|
@ -615,17 +617,17 @@ namespace
|
|||
}
|
||||
|
||||
void draw_rectangle(uint8_t* data, uint32_t pitch, uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2,
|
||||
uint32_t color, uint32_t thickness)
|
||||
uint16_t color, uint32_t thickness)
|
||||
{
|
||||
for(uint32_t i = x1; i < x2; i++)
|
||||
for(uint32_t j = 0; j < thickness; j++) {
|
||||
reinterpret_cast<uint32_t*>(data + pitch * (y1 + j))[i] = color;
|
||||
reinterpret_cast<uint32_t*>(data + pitch * (y2 - 1 - j))[i] = color;
|
||||
reinterpret_cast<uint16_t*>(data + pitch * (y1 + j))[i] = color;
|
||||
reinterpret_cast<uint16_t*>(data + pitch * (y2 - 1 - j))[i] = color;
|
||||
}
|
||||
for(uint32_t i = y1; i < y2; i++)
|
||||
for(uint32_t j = 0; j < thickness; j++) {
|
||||
reinterpret_cast<uint32_t*>(data + pitch * i)[x1 + j] = color;
|
||||
reinterpret_cast<uint32_t*>(data + pitch * i)[x2 - 1 - j] = color;
|
||||
reinterpret_cast<uint16_t*>(data + pitch * i)[x1 + j] = color;
|
||||
reinterpret_cast<uint16_t*>(data + pitch * i)[x2 - 1 - j] = color;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -658,7 +660,7 @@ namespace
|
|||
void draw_string(uint8_t* base, uint32_t pitch, std::vector<uint32_t> s, uint32_t x, uint32_t y,
|
||||
uint32_t maxwidth, uint32_t hilite_mode = 0, uint32_t hilite_pos = 0)
|
||||
{
|
||||
base += y * static_cast<size_t>(pitch) + 4 * x;
|
||||
base += y * static_cast<size_t>(pitch) + 2 * x;
|
||||
int32_t pos_x = 0;
|
||||
int32_t pos_y = 0;
|
||||
unsigned c = 0;
|
||||
|
@ -675,35 +677,34 @@ namespace
|
|||
if(g.second == 0) {
|
||||
//Empty glyph.
|
||||
for(unsigned j = 0; j < 16; j++) {
|
||||
uint32_t* ptr = reinterpret_cast<uint32_t*>(base + pitch * j);
|
||||
uint16_t* ptr = reinterpret_cast<uint16_t*>(base + pitch * j);
|
||||
for(unsigned i = 0; i < g.first && old_x + i < maxwidth; i++)
|
||||
ptr[old_x + i] = (j >= curstart) ? 0xFFFFFFFFU : 0;
|
||||
ptr[old_x + i] = (j >= curstart) ? 0x7FFFU : 0;
|
||||
}
|
||||
} else {
|
||||
//Narrow/Wide glyph.
|
||||
for(unsigned j = 0; j < 16; j++) {
|
||||
uint32_t* ptr = reinterpret_cast<uint32_t*>(base + pitch * j);
|
||||
uint16_t* ptr = reinterpret_cast<uint16_t*>(base + pitch * j);
|
||||
uint32_t dataword = fontdata[g.second + j / 4];
|
||||
for(uint32_t i = 0; i < g.first && old_x + i < maxwidth; i++) {
|
||||
bool b = (((dataword >> (31 - (j % (32 / g.first)) * g.first - i)) &
|
||||
1));
|
||||
b ^= (j >= curstart);
|
||||
ptr[old_x + i] = b ? 0xFFFFFFFFU : 0;
|
||||
ptr[old_x + i] = b ? 0x7FFFU : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
c++;
|
||||
}
|
||||
for(unsigned j = 0; j < 16; j++) {
|
||||
uint32_t* ptr = reinterpret_cast<uint32_t*>(base + pitch * j);
|
||||
uint16_t* ptr = reinterpret_cast<uint16_t*>(base + pitch * j);
|
||||
uint32_t curstart = 16;
|
||||
if(c == hilite_pos && hilite_mode == 1)
|
||||
curstart = 14;
|
||||
if(c == hilite_pos && hilite_mode == 2)
|
||||
curstart = 0;
|
||||
for(uint32_t i = pos_x; i < maxwidth; i++) {
|
||||
ptr[i] = ((i - pos_x) < 8 && j >= curstart) ? 0xFFFFFFFFU : 0;
|
||||
}
|
||||
for(uint32_t i = pos_x; i < maxwidth; i++)
|
||||
ptr[i] = ((i - pos_x) < 8 && j >= curstart) ? 0x7FFFU : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -760,11 +761,10 @@ namespace
|
|||
y1 = (surf->h - height) / 2;
|
||||
y2 = y1 + height;
|
||||
}
|
||||
SDL_LockSurface(surf);
|
||||
for(uint32_t j = y1 - 6; j < y2 + 6; j++)
|
||||
memset(reinterpret_cast<uint8_t*>(surf->pixels) + j * surf->pitch + 4 * (x1 - 6), 0,
|
||||
4 * (x2 - x1 + 12));
|
||||
uint32_t bordercolor = (128 << surf->format->Gshift) | (255 << surf->format->Rshift);
|
||||
memset(reinterpret_cast<uint8_t*>(surf->pixels) + j * surf->pitch + 2 * (x1 - 6), 0,
|
||||
2 * (x2 - x1 + 12));
|
||||
uint16_t bordercolor = 0x7E00;
|
||||
draw_rectangle(reinterpret_cast<uint8_t*>(surf->pixels), surf->pitch, x1 - 4, y1 - 4, x2 + 4, y2 + 4,
|
||||
bordercolor, 2);
|
||||
|
||||
|
@ -777,11 +777,11 @@ namespace
|
|||
if(static_cast<uint32_t>(pos_y) > height)
|
||||
break;
|
||||
uint8_t* base = reinterpret_cast<uint8_t*>(surf->pixels) + (y1 + oy) * surf->pitch +
|
||||
4 * (x1 + ox);
|
||||
2 * (x1 + ox);
|
||||
if(g.second) {
|
||||
//Narrow/Wide glyph.
|
||||
for(unsigned j = 0; j < 16; j++) {
|
||||
uint32_t* ptr = reinterpret_cast<uint32_t*>(base + surf->pitch * j);
|
||||
uint16_t* ptr = reinterpret_cast<uint16_t*>(base + surf->pitch * j);
|
||||
uint32_t dataword = fontdata[g.second + j / 4];
|
||||
for(uint32_t i = 0; i < g.first && (ox + i) < width; i++) {
|
||||
bool b = (((dataword >> (31 - (j % (32 / g.first)) * g.first - i)) &
|
||||
|
@ -789,7 +789,6 @@ namespace
|
|||
ptr[i] = b ? bordercolor : 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1087,6 +1086,7 @@ void window::init()
|
|||
current_screen = NULL;
|
||||
pause_active = false;
|
||||
hwsurf = NULL;
|
||||
swsurf = NULL;
|
||||
command_overwrite = false;
|
||||
old_screen_h = 0;
|
||||
old_screen_w = 0;
|
||||
|
@ -1205,108 +1205,125 @@ void window::set_main_surface(screen& scr) throw()
|
|||
notify_screen_update(true);
|
||||
}
|
||||
|
||||
void window::notify_screen_update(bool full) throw()
|
||||
namespace
|
||||
{
|
||||
bool is_time_for_screen_update(bool full)
|
||||
{
|
||||
uint64_t curtime = get_ticks_msec();
|
||||
//Always do full updates.
|
||||
if(!full && last_ui_update < curtime && last_ui_update + MIN_UPDATE_TIME > curtime) {
|
||||
screen_is_dirty = true;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
last_ui_update = curtime;
|
||||
screen_is_dirty = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::pair<uint32_t, uint32_t> compute_screen_size(uint32_t width, uint32_t height)
|
||||
{
|
||||
if(width < 512)
|
||||
width = 512;
|
||||
if(height < 448)
|
||||
height = 448;
|
||||
return std::make_pair(width, height);
|
||||
}
|
||||
|
||||
std::pair<uint32_t, uint32_t> compute_window_size(uint32_t width, uint32_t height)
|
||||
{
|
||||
auto g = compute_screen_size(width, height);
|
||||
uint32_t win_w = ((g.first + 15) >> 4 << 4) + 278;
|
||||
uint32_t win_h = g.second + MAXMESSAGES * 16 + 48;
|
||||
return std::make_pair(win_w, win_h);
|
||||
}
|
||||
|
||||
void show_fps()
|
||||
{
|
||||
try {
|
||||
std::ostringstream y;
|
||||
y << get_framerate();
|
||||
emustatus["FPS"] = y.str();
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
std::string command_showas = decode_string(command_buf);
|
||||
uint32_t screen_w = 512;
|
||||
uint32_t screen_h = 448;
|
||||
if(current_screen && current_screen->width >= 512 && current_screen->height >= 448) {
|
||||
screen_w = current_screen->width;
|
||||
screen_h = current_screen->height;
|
||||
}
|
||||
uint32_t win_w = ((screen_w < 512) ? 512 : ((screen_w + 15) / 16 * 16)) + 278;
|
||||
uint32_t win_h = screen_h + MAXMESSAGES * 16 + 48;
|
||||
if(!hwsurf || static_cast<uint32_t>(hwsurf->w) != win_w || static_cast<uint32_t>(hwsurf->h) != win_h ||
|
||||
old_screen_w != screen_w || old_screen_h != screen_h || full) {
|
||||
//Create/Resize the window.
|
||||
if(!hwsurf || static_cast<uint32_t>(hwsurf->w) != win_w || static_cast<uint32_t>(hwsurf->h) != win_h) {
|
||||
SDL_Surface* hwsurf2 = SDL_SetVideoMode(win_w, win_h, 32, SDL_SWSURFACE | SDL_DOUBLEBUF);
|
||||
if(!hwsurf2) {
|
||||
//We are in too fucked up state to even print error as message.
|
||||
std::cout << "PANIC: Can't create/resize window: " << SDL_GetError() << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
hwsurf = hwsurf2;
|
||||
}
|
||||
if(current_screen)
|
||||
current_screen->set_palette(hwsurf->format->Rshift, hwsurf->format->Gshift,
|
||||
hwsurf->format->Bshift);
|
||||
void redraw_borders(SDL_Surface* swsurf, std::pair<uint32_t, uint32_t> screensize,
|
||||
std::pair<uint32_t, uint32_t> windowsize)
|
||||
{
|
||||
//Blank the screen and draw borders.
|
||||
SDL_LockSurface(hwsurf);
|
||||
memset(hwsurf->pixels, 0, win_h * hwsurf->pitch);
|
||||
uint32_t bordercolor = 255 << hwsurf->format->Gshift;
|
||||
if(console_mode) {
|
||||
draw_rectangle(reinterpret_cast<uint8_t*>(hwsurf->pixels), hwsurf->pitch, 2, 2, win_w - 2,
|
||||
win_h - 28, bordercolor, 2);
|
||||
draw_rectangle(reinterpret_cast<uint8_t*>(hwsurf->pixels), hwsurf->pitch, 2, win_h - 26,
|
||||
win_w - 2, win_h - 2, bordercolor, 2);
|
||||
} else {
|
||||
draw_rectangle(reinterpret_cast<uint8_t*>(hwsurf->pixels), hwsurf->pitch, 2, 2, screen_w + 10,
|
||||
screen_h + 10, bordercolor, 2);
|
||||
draw_rectangle(reinterpret_cast<uint8_t*>(hwsurf->pixels), hwsurf->pitch, screen_w + 12, 2,
|
||||
screen_w + 276, screen_h + 10, bordercolor, 2);
|
||||
draw_rectangle(reinterpret_cast<uint8_t*>(hwsurf->pixels), hwsurf->pitch, 2, screen_h + 12,
|
||||
win_w - 2, screen_h + MAXMESSAGES * 16 + 20, bordercolor, 2);
|
||||
draw_rectangle(reinterpret_cast<uint8_t*>(hwsurf->pixels), hwsurf->pitch, 2,
|
||||
screen_h + MAXMESSAGES * 16 + 22, win_w - 2, screen_h + MAXMESSAGES * 16 + 46,
|
||||
bordercolor, 2);
|
||||
}
|
||||
SDL_UnlockSurface(hwsurf);
|
||||
old_screen_w = screen_w;
|
||||
old_screen_h = screen_h;
|
||||
}
|
||||
SDL_LockSurface(hwsurf);
|
||||
memset(swsurf->pixels, 0, windowsize.second * swsurf->pitch);
|
||||
uint32_t bordercolor = 0x03E0;
|
||||
uint32_t msgbox_min_x = 2;
|
||||
uint32_t msgbox_min_y = 2;
|
||||
uint32_t msgbox_max_x = windowsize.first - 2;
|
||||
uint32_t msgbox_max_y = windowsize.second - 28;
|
||||
uint32_t cmdbox_min_x = 2;
|
||||
uint32_t cmdbox_max_x = windowsize.first - 2;
|
||||
uint32_t cmdbox_min_y = windowsize.second - 26;
|
||||
uint32_t cmdbox_max_y = windowsize.second - 2;
|
||||
if(!console_mode) {
|
||||
if(current_screen) {
|
||||
//Draw main screen (blanking background if needed).
|
||||
if(screen_w < current_screen->width || screen_h < current_screen->height)
|
||||
for(uint32_t i = 6; i < screen_h + 6; i++)
|
||||
memset(reinterpret_cast<uint8_t*>(hwsurf->pixels) + i * hwsurf->pitch + 24, 0,
|
||||
4 * screen_w);
|
||||
for(uint32_t i = 0; i < current_screen->height; i++)
|
||||
memcpy(reinterpret_cast<uint8_t*>(hwsurf->pixels) + (i + 6) * hwsurf->pitch + 24,
|
||||
reinterpret_cast<uint8_t*>(current_screen->memory) + current_screen->pitch * i,
|
||||
4 * current_screen->width);
|
||||
} else {
|
||||
//Draw blank.
|
||||
for(uint32_t i = 6; i < screen_h + 6; i++)
|
||||
memset(reinterpret_cast<uint8_t*>(hwsurf->pixels) + i * hwsurf->pitch + 24, 0,
|
||||
4 * screen_w);
|
||||
uint32_t scrbox_min_x = 2;
|
||||
uint32_t scrbox_max_x = screensize.first + 10;
|
||||
uint32_t scrbox_min_y = 2;
|
||||
uint32_t scrbox_max_y = screensize.second + 10;
|
||||
uint32_t stsbox_min_x = screensize.first + 12;
|
||||
uint32_t stsbox_max_x = windowsize.first - 2;
|
||||
uint32_t stsbox_min_y = 2;
|
||||
uint32_t stsbox_max_y = screensize.second + 10;
|
||||
uint32_t msgbox_min_y = screensize.second + 12;
|
||||
draw_rectangle(reinterpret_cast<uint8_t*>(swsurf->pixels), swsurf->pitch, scrbox_min_x,
|
||||
scrbox_min_y, scrbox_max_x, scrbox_max_y, bordercolor, 2);
|
||||
draw_rectangle(reinterpret_cast<uint8_t*>(swsurf->pixels), swsurf->pitch, stsbox_min_x,
|
||||
stsbox_min_y, stsbox_max_x, stsbox_max_y, bordercolor, 2);
|
||||
}
|
||||
//Draw status.
|
||||
uint32_t status_x = screen_w + 16;
|
||||
draw_rectangle(reinterpret_cast<uint8_t*>(swsurf->pixels), swsurf->pitch, msgbox_min_x,
|
||||
msgbox_min_y, msgbox_max_x, msgbox_max_y, bordercolor, 2);
|
||||
draw_rectangle(reinterpret_cast<uint8_t*>(swsurf->pixels), swsurf->pitch, cmdbox_min_x,
|
||||
cmdbox_min_y, cmdbox_max_x, cmdbox_max_y, bordercolor, 2);
|
||||
}
|
||||
|
||||
void draw_main_screen(SDL_Surface* swsurf, std::pair<uint32_t, uint32_t> screensize)
|
||||
{
|
||||
uint32_t cw = current_screen ? current_screen->width : 0;
|
||||
uint32_t ch = current_screen ? current_screen->height : 0;
|
||||
//Blank parts not drawn.
|
||||
for(uint32_t i = 6; i < ch + 6; i++)
|
||||
memset(reinterpret_cast<uint8_t*>(swsurf->pixels) + i * swsurf->pitch + 12 + 2 * cw, 0,
|
||||
2 * (screensize.first - cw));
|
||||
for(uint32_t i = ch + 6; i < screensize.second + 6; i++)
|
||||
memset(reinterpret_cast<uint8_t*>(swsurf->pixels) + i * swsurf->pitch + 12, 0,
|
||||
2 * screensize.first);
|
||||
if(current_screen) {
|
||||
for(uint32_t i = 0; i < ch; i++)
|
||||
memcpy(reinterpret_cast<uint8_t*>(swsurf->pixels) + (i + 6) * swsurf->pitch + 12,
|
||||
reinterpret_cast<uint8_t*>(current_screen->memory) + current_screen->pitch * i,
|
||||
2 * cw);
|
||||
}
|
||||
}
|
||||
|
||||
void draw_status_area(SDL_Surface* swsurf, std::pair<uint32_t, uint32_t> screensize)
|
||||
{
|
||||
uint32_t status_x = screensize.first + 16;
|
||||
uint32_t status_y = 6;
|
||||
for(auto i = emustatus.begin(); i != emustatus.end(); i++) {
|
||||
std::string msg = i->first + " " + i->second;
|
||||
draw_string(reinterpret_cast<uint8_t*>(hwsurf->pixels), hwsurf->pitch, msg, status_x, status_y,
|
||||
draw_string(reinterpret_cast<uint8_t*>(swsurf->pixels), swsurf->pitch, msg, status_x, status_y,
|
||||
256);
|
||||
status_y += 16;
|
||||
}
|
||||
while(status_y - 6 < screen_h / 16 * 16) {
|
||||
draw_string(reinterpret_cast<uint8_t*>(hwsurf->pixels), hwsurf->pitch, "", status_x, status_y,
|
||||
while(status_y - 6 < screensize.second / 16 * 16) {
|
||||
draw_string(reinterpret_cast<uint8_t*>(swsurf->pixels), swsurf->pitch, "", status_x, status_y,
|
||||
256);
|
||||
status_y += 16;
|
||||
}
|
||||
}
|
||||
//Draw messages.
|
||||
|
||||
void draw_messages(SDL_Surface* swsurf, std::pair<uint32_t, uint32_t> screensize,
|
||||
std::pair<uint32_t, uint32_t> windowsize)
|
||||
{
|
||||
uint32_t message_y;
|
||||
if(!console_mode)
|
||||
message_y = screen_h + 16;
|
||||
message_y = screensize.second + 16;
|
||||
else
|
||||
message_y = 6;
|
||||
for(size_t j = 0; j < maxmessages; j++)
|
||||
|
@ -1315,36 +1332,84 @@ void window::notify_screen_update(bool full) throw()
|
|||
if(messagebuffer_first_show + j < messagebuffer_next_seq)
|
||||
o << (messagebuffer_first_show + j + 1) << ": "
|
||||
<< messagebuffer[messagebuffer_first_show + j];
|
||||
draw_string(reinterpret_cast<uint8_t*>(hwsurf->pixels), hwsurf->pitch, o.str(), 6,
|
||||
message_y + 16 * j, win_w - 12);
|
||||
draw_string(reinterpret_cast<uint8_t*>(swsurf->pixels), swsurf->pitch, o.str(), 6,
|
||||
message_y + 16 * j, windowsize.first - 12);
|
||||
} catch(...) {
|
||||
}
|
||||
if(messagebuffer_next_seq - messagebuffer_first_show > maxmessages)
|
||||
try {
|
||||
draw_string(reinterpret_cast<uint8_t*>(hwsurf->pixels), hwsurf->pitch, "--More--", win_w - 76,
|
||||
message_y + 16 * maxmessages - 16, 64);
|
||||
draw_string(reinterpret_cast<uint8_t*>(swsurf->pixels), swsurf->pitch, "--More--",
|
||||
windowsize.first - 76, message_y + 16 * maxmessages - 16, 64);
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
//Draw command_buf.
|
||||
uint32_t command_y = win_h - 22;
|
||||
void draw_command(SDL_Surface* swsurf, std::pair<uint32_t, uint32_t> windowsize)
|
||||
{
|
||||
uint32_t command_y = windowsize.second - 22;
|
||||
try {
|
||||
std::string command_showas = decode_string(command_buf);
|
||||
if(state == WINSTATE_COMMAND)
|
||||
draw_command(reinterpret_cast<uint8_t*>(hwsurf->pixels), hwsurf->pitch, command_showas,
|
||||
command_cursor / 4, 6, command_y, win_w - 12, command_overwrite);
|
||||
draw_command(reinterpret_cast<uint8_t*>(swsurf->pixels), swsurf->pitch, command_showas,
|
||||
command_cursor / 4, 6, command_y, windowsize.first - 12, command_overwrite);
|
||||
else
|
||||
draw_string(reinterpret_cast<uint8_t*>(hwsurf->pixels), hwsurf->pitch, "", 6, command_y,
|
||||
win_w - 12);
|
||||
draw_string(reinterpret_cast<uint8_t*>(swsurf->pixels), swsurf->pitch, "", 6,
|
||||
command_y, windowsize.first - 12);
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void window::notify_screen_update(bool full) throw()
|
||||
{
|
||||
bool resize_screen = false;
|
||||
if(!is_time_for_screen_update(full))
|
||||
return;
|
||||
auto windowsize = compute_window_size(current_screen ? current_screen->width : 0, current_screen ?
|
||||
current_screen->height : 0);
|
||||
auto screensize = compute_screen_size(current_screen ? current_screen->width : 0, current_screen ?
|
||||
current_screen->height : 0);
|
||||
show_fps();
|
||||
|
||||
|
||||
if(!hwsurf || windowsize != current_windowsize) {
|
||||
//Create/Resize the window.
|
||||
SDL_Surface* hwsurf2 = SDL_SetVideoMode(windowsize.first, windowsize.second, 0, SDL_SWSURFACE |
|
||||
SDL_ANYFORMAT);
|
||||
SDL_Surface* swsurf2 = SDL_CreateRGBSurface(SDL_SWSURFACE, windowsize.first, windowsize.second, 16,
|
||||
0x7E00, 0x03E0, 0x001F, 0);
|
||||
if(!hwsurf2 || !swsurf2) {
|
||||
//We are in too fucked up state to even print error as message.
|
||||
std::cout << "PANIC: Can't create/resize window: " << SDL_GetError() << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
if(swsurf)
|
||||
SDL_FreeSurface(swsurf);
|
||||
hwsurf = hwsurf2;
|
||||
swsurf = swsurf2;
|
||||
full = true;
|
||||
current_windowsize = windowsize;
|
||||
}
|
||||
|
||||
SDL_LockSurface(swsurf);
|
||||
if(full)
|
||||
redraw_borders(swsurf, screensize, windowsize);
|
||||
if(!console_mode) {
|
||||
draw_main_screen(swsurf, screensize);
|
||||
draw_status_area(swsurf, screensize);
|
||||
}
|
||||
draw_messages(swsurf, screensize, windowsize);
|
||||
draw_command(swsurf, windowsize);
|
||||
|
||||
//Draw modal dialog.
|
||||
if(state == WINSTATE_MODAL)
|
||||
try {
|
||||
draw_modal_dialog(hwsurf, modmsg, modconfirm);
|
||||
draw_modal_dialog(swsurf, modmsg, modconfirm);
|
||||
} catch(...) {
|
||||
}
|
||||
SDL_UnlockSurface(hwsurf);
|
||||
SDL_Flip(hwsurf);
|
||||
SDL_UnlockSurface(swsurf);
|
||||
SDL_BlitSurface(swsurf, NULL, hwsurf, NULL);
|
||||
SDL_UpdateRect(hwsurf, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void poll_inputs_internal() throw(std::bad_alloc)
|
||||
|
@ -1456,7 +1521,7 @@ namespace
|
|||
[]() throw(std::bad_alloc, std::runtime_error) {
|
||||
console_mode = !console_mode;
|
||||
if(console_mode)
|
||||
maxmessages = hwsurf ? (hwsurf->h - 38) / 16 : 36;
|
||||
maxmessages = swsurf ? (swsurf->h - 38) / 16 : 36;
|
||||
else
|
||||
maxmessages = MAXMESSAGES;
|
||||
if(messagebuffer_next_seq < maxmessages)
|
||||
|
|
|
@ -47,9 +47,6 @@ namespace
|
|||
hscl = 2;
|
||||
if(dump_large && _frame.height < 400)
|
||||
vscl = 2;
|
||||
uint32_t _magic = 403703808;
|
||||
uint8_t* magic = reinterpret_cast<uint8_t*>(&_magic);
|
||||
dscr.set_palette(magic[2], magic[1], magic[0]);
|
||||
|
||||
struct lua_render_context lrc;
|
||||
render_queue rq;
|
||||
|
@ -60,9 +57,6 @@ namespace
|
|||
lrc.queue = &rq;
|
||||
lrc.width = _frame.width * hscl;
|
||||
lrc.height = _frame.height * vscl;
|
||||
lrc.rshift = magic[2];
|
||||
lrc.gshift = magic[1];
|
||||
lrc.bshift = magic[0];
|
||||
lua_callback_do_video(&lrc);
|
||||
|
||||
dscr.reallocate(lrc.left_gap + hscl * _frame.width + lrc.right_gap, lrc.top_gap + vscl *
|
||||
|
|
|
@ -126,7 +126,7 @@ void avidumper::on_sample(short left, short right) throw(std::bad_alloc, std::ru
|
|||
audio_put_ptr = 0;
|
||||
}
|
||||
|
||||
void avidumper::on_frame(const uint32_t* data, uint16_t width, uint16_t height, uint32_t fps_n, uint32_t fps_d)
|
||||
void avidumper::on_frame(const uint16_t* data, uint16_t width, uint16_t height, uint32_t fps_n, uint32_t fps_d)
|
||||
throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
if(capture_error)
|
||||
|
@ -202,8 +202,8 @@ void avidumper::print_summary(std::ostream& str)
|
|||
str << s2.str();
|
||||
}
|
||||
|
||||
void avidumper::on_frame_threaded(const uint32_t* data, uint16_t width, uint16_t height, uint32_t fps_n, uint32_t fps_d)
|
||||
throw(std::bad_alloc, std::runtime_error)
|
||||
void avidumper::on_frame_threaded(const uint16_t* data, uint16_t width, uint16_t height, uint32_t fps_n,
|
||||
uint32_t fps_d) throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
//The AVI part of sound to write is [audio_get, audio_commit). We don't write part [audio_commit,audio_put)
|
||||
//yet, as it is being concurrently written. Also grab lock to read the commit value. Also, if global frame
|
||||
|
@ -219,31 +219,49 @@ void avidumper::on_frame_threaded(const uint32_t* data, uint16_t width, uint16_t
|
|||
if(segment_movi_ptr > AVI_CUTOFF - 16 * segment_chunks.size() || (maxframes && segment_frames > maxframes))
|
||||
fixup_avi_header_and_close();
|
||||
|
||||
uint16_t rwidth = (width + 3) / 4 * 4;
|
||||
uint16_t rheight = (height + 3) / 4 * 4;
|
||||
bool this_is_keyframe;
|
||||
if(width != pwidth || height != pheight || fps_n != pfps_n || fps_d != pfps_d || !avi_open) {
|
||||
if(rwidth != pwidth || rheight != pheight || fps_n != pfps_n || fps_d != pfps_d || !avi_open) {
|
||||
std::cerr << "Starting segment # " << current_segment << ": " << width << "x" << height << "."
|
||||
<< std::endl;
|
||||
fixup_avi_header_and_close();
|
||||
pwidth = width;
|
||||
pheight = height;
|
||||
pwidth = rwidth;
|
||||
pheight = rheight;
|
||||
pfps_n = fps_n;
|
||||
pfps_d = fps_d;
|
||||
pframe.resize(4 * static_cast<size_t>(width) * height);
|
||||
tframe.resize(4 * static_cast<size_t>(width) * rheight);
|
||||
cframe.resize(compressBound(4 * static_cast<size_t>(width) * rheight) + 13);
|
||||
memset(&tframe[0], 0, 4 * static_cast<size_t>(width) * rheight);
|
||||
open_and_write_avi_header(width, rheight, fps_n, fps_d);
|
||||
pframe.resize(2 * static_cast<size_t>(rwidth) * rheight);
|
||||
tframe.resize(2 * static_cast<size_t>(rwidth) * rheight);
|
||||
cframe.resize(compressBound(tframe.size()) + 13);
|
||||
memset(&tframe[0], 0, tframe.size());
|
||||
memset(&pframe[0], 0, pframe.size());
|
||||
open_and_write_avi_header(rwidth, rheight, fps_n, fps_d);
|
||||
}
|
||||
|
||||
this_is_keyframe = (segment_frames == 0 || segment_frames - segment_last_keyframe >= keyframe_interval);
|
||||
uint8_t _magic[2] = {2, 1};
|
||||
uint16_t magic = *reinterpret_cast<uint16_t*>(_magic);
|
||||
|
||||
if(this_is_keyframe) {
|
||||
memcpy(&tframe[0], data, 4 * static_cast<size_t>(width) * height);
|
||||
for(size_t i = 0; i < height; i++)
|
||||
memcpy(&tframe[2 * i * rwidth], data + (i * width), 2 * width);
|
||||
if(magic != 258)
|
||||
for(size_t i = 0; i < tframe.size(); i += 2) {
|
||||
tframe[i] ^= tframe[i + 1];
|
||||
tframe[i + 1] ^= tframe[i];
|
||||
tframe[i] ^= tframe[i + 1];
|
||||
}
|
||||
segment_last_keyframe = segment_frames;
|
||||
} else {
|
||||
memcpy(&tframe[0], data, 4 * static_cast<size_t>(width) * height);
|
||||
for(size_t i = 0; i < 4 * static_cast<size_t>(width) * height; i++)
|
||||
for(size_t i = 0; i < height; i++)
|
||||
memcpy(&tframe[2 * i * rwidth], data + (i * width), 2 * width);
|
||||
if(magic != 258)
|
||||
for(size_t i = 0; i < tframe.size(); i += 2) {
|
||||
tframe[i] ^= tframe[i + 1];
|
||||
tframe[i + 1] ^= tframe[i];
|
||||
tframe[i] ^= tframe[i + 1];
|
||||
}
|
||||
for(size_t i = 0; i < tframe.size(); i++)
|
||||
tframe[i] -= pframe[i];
|
||||
}
|
||||
uLongf l = cframe.size() - 10;
|
||||
|
@ -261,7 +279,7 @@ void avidumper::on_frame_threaded(const uint32_t* data, uint16_t width, uint16_t
|
|||
cframe[6] = (l + 2) >> 16;
|
||||
cframe[7] = (l + 2) >> 24;
|
||||
cframe[8] = (this_is_keyframe ? 0x3 : 0x2) | (compression_level << 4);
|
||||
cframe[9] = 12;
|
||||
cframe[9] = 4;
|
||||
avi_stream.write(reinterpret_cast<char*>(&cframe[0]), l + 10);
|
||||
if(!avi_stream)
|
||||
throw std::runtime_error("Error writing video frame");
|
||||
|
@ -276,7 +294,14 @@ void avidumper::on_frame_threaded(const uint32_t* data, uint16_t width, uint16_t
|
|||
if((segment_frames % 1200) == 0)
|
||||
print_summary(std::cerr);
|
||||
|
||||
memcpy(&pframe[0], data, 4 * static_cast<size_t>(width) * height);
|
||||
for(size_t i = 0; i < height; i++)
|
||||
memcpy(&pframe[2 * i * rwidth], data + (i * width), 2 * width);
|
||||
if(magic != 258)
|
||||
for(size_t i = 0; i < pframe.size(); i += 2) {
|
||||
pframe[i] ^= pframe[i + 1];
|
||||
pframe[i + 1] ^= pframe[i];
|
||||
pframe[i] ^= pframe[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
void avidumper::on_end() throw(std::bad_alloc, std::runtime_error)
|
||||
|
@ -477,16 +502,16 @@ void avidumper::open_and_write_avi_header(uint16_t width, uint16_t height, uint3
|
|||
ptr(fixup_avi_length), u32(0), /* Video length (to be fixed later). */
|
||||
u32(1000000), /* Suggested buffer size... Just give some random value. */
|
||||
u32(9999), /* Quality... Doesn't matter. */
|
||||
u32(4), /* Video sample size... 32bpp. */
|
||||
u32(2), /* Video sample size... 16bpp. */
|
||||
u32(0), u32(0), /* Bounding box upper left. */
|
||||
u32(width), u32(height)); /* Bounding box lower right. */
|
||||
/* BITMAPINFO header for the video stream. */
|
||||
append(aviheader, str("strf"), u32(40), /* 40 byte header of type strf. */
|
||||
u32(40), /* BITMAPINFOHEADER is 40 bytes. */
|
||||
u32(width), u32(height), /* Image size. */
|
||||
u16(1), u16(32), /* 1 plane, 32 bits (RGB32). */
|
||||
u16(1), u16(16), /* 1 plane, 16 bits (RGB16). */
|
||||
str("CSCD"), /* Compressed with Camstudio codec. */
|
||||
u32(4 * width * height), /* Image size. */
|
||||
u32(2 * width * height), /* Image size. */
|
||||
u32(4000), u32(4000), /* Resolution... Give some random values. */
|
||||
u32(0), u32(0)); /* Colors used values (0 => All colors used). */
|
||||
/* Stream list header For stream #2, 104 bytes of data. */
|
||||
|
|
|
@ -190,7 +190,7 @@ public:
|
|||
* throws std::bad_alloc: Not enough memory.
|
||||
* throws std::runtime_error: Error dumping frame.
|
||||
*/
|
||||
void on_frame(const uint32_t* data, uint16_t width, uint16_t height, uint32_t fps_n, uint32_t fps_d)
|
||||
void on_frame(const uint16_t* data, uint16_t width, uint16_t height, uint32_t fps_n, uint32_t fps_d)
|
||||
throw(std::bad_alloc, std::runtime_error);
|
||||
|
||||
/**
|
||||
|
@ -226,7 +226,7 @@ public:
|
|||
void set_capture_error(const char* err) throw();
|
||||
private:
|
||||
void print_summary(std::ostream& str);
|
||||
void on_frame_threaded(const uint32_t* data, uint16_t width, uint16_t height, uint32_t fps_n, uint32_t fps_d)
|
||||
void on_frame_threaded(const uint16_t* data, uint16_t width, uint16_t height, uint32_t fps_n, uint32_t fps_d)
|
||||
throw(std::bad_alloc, std::runtime_error);
|
||||
void flush_audio_to(unsigned commit_ptr);
|
||||
void open_and_write_avi_header(uint16_t width, uint16_t height, uint32_t fps_n, uint32_t fps_d);
|
||||
|
@ -274,7 +274,7 @@ private:
|
|||
thread_class* frame_thread;
|
||||
cv_class frame_cond;
|
||||
mutex_class frame_mutex;
|
||||
const uint32_t* mt_data;
|
||||
const uint16_t* mt_data;
|
||||
volatile uint16_t mt_width;
|
||||
volatile uint16_t mt_height;
|
||||
volatile uint32_t mt_fps_n;
|
||||
|
|
|
@ -128,9 +128,6 @@ void redraw_framebuffer()
|
|||
lrc.queue = &rq;
|
||||
lrc.width = framebuffer.width * hscl;
|
||||
lrc.height = framebuffer.height * vscl;
|
||||
lrc.rshift = main_screen.active_rshift;
|
||||
lrc.gshift = main_screen.active_gshift;
|
||||
lrc.bshift = main_screen.active_bshift;
|
||||
lua_callback_do_paint(&lrc);
|
||||
main_screen.reallocate(framebuffer.width * hscl + lrc.left_gap + lrc.right_gap, framebuffer.height * vscl +
|
||||
lrc.top_gap + lrc.bottom_gap, lrc.left_gap, lrc.top_gap);
|
||||
|
|
|
@ -63,9 +63,6 @@ struct lua_render_context
|
|||
struct render_queue* queue;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t rshift;
|
||||
uint32_t gshift;
|
||||
uint32_t bshift;
|
||||
};
|
||||
|
||||
void init_lua() throw();
|
||||
|
|
|
@ -29,12 +29,20 @@ extern uint32_t fontdata[];
|
|||
|
||||
namespace
|
||||
{
|
||||
inline uint32_t blend(uint32_t orig, uint16_t ialpha, uint32_t pl, uint32_t ph) throw()
|
||||
std::pair<uint32_t, uint32_t> premultipy_color(uint16_t color, uint8_t alpha)
|
||||
{
|
||||
const uint32_t X = 0xFF00FFU;
|
||||
const uint32_t Y = 0xFF00FF00U;
|
||||
return ((ialpha * ((orig >> 8) & X) + ph) & Y) | (((ialpha * (orig & X) + pl)
|
||||
>> 8) & X);
|
||||
uint32_t a, b;
|
||||
a = color & 0x7C1F;
|
||||
b = color & 0x03E0;
|
||||
return std::make_pair(a * alpha, b * alpha);
|
||||
}
|
||||
|
||||
inline uint16_t blend(uint16_t orig, uint8_t ialpha, std::pair<uint32_t, uint32_t> with) throw()
|
||||
{
|
||||
uint32_t a, b;
|
||||
a = orig & 0x7C1F;
|
||||
b = orig & 0x03E0;
|
||||
return (((a * ialpha + with.first) >> 5) & 0x7C1F) | (((b * ialpha + with.second) >> 5) & 0x03E0);
|
||||
}
|
||||
|
||||
//This is Jenkin's MIX function.
|
||||
|
@ -107,15 +115,13 @@ render_object::~render_object() throw()
|
|||
{
|
||||
}
|
||||
|
||||
void render_text(struct screen& scr, int32_t x, int32_t y, const std::string& text, uint32_t fg,
|
||||
uint16_t fgalpha, uint32_t bg, uint16_t bgalpha) throw(std::bad_alloc)
|
||||
void render_text(struct screen& scr, int32_t x, int32_t y, const std::string& text, uint16_t fg,
|
||||
uint8_t fgalpha, uint16_t bg, uint8_t bgalpha) throw(std::bad_alloc)
|
||||
{
|
||||
uint32_t pfgl = (fg & 0xFF00FF) * fgalpha;
|
||||
uint32_t pfgh = ((fg >> 8) & 0xFF00FF) * fgalpha;
|
||||
uint32_t pbgl = (bg & 0xFF00FF) * bgalpha;
|
||||
uint32_t pbgh = ((bg >> 8) & 0xFF00FF) * bgalpha;
|
||||
uint16_t ifga = 256 - fgalpha;
|
||||
uint16_t ibga = 256 - bgalpha;
|
||||
auto pfg = premultipy_color(fg, fgalpha);
|
||||
auto pbg = premultipy_color(bg, bgalpha);
|
||||
uint8_t ifga = 32 - fgalpha;
|
||||
uint8_t ibga = 32 - bgalpha;
|
||||
int32_t orig_x = x;
|
||||
uint32_t unicode_code = 0;
|
||||
uint8_t unicode_left = 0;
|
||||
|
@ -171,20 +177,20 @@ void render_text(struct screen& scr, int32_t x, int32_t y, const std::string& te
|
|||
if(p.second == 0) {
|
||||
//Blank glyph.
|
||||
for(uint32_t j = 0; j < dh; j++) {
|
||||
uint32_t* base = scr.rowptr(cy + j) + cx;
|
||||
uint16_t* base = scr.rowptr(cy + j) + cx;
|
||||
for(uint32_t i = 0; i < dw; i++)
|
||||
base[i] = blend(base[i], ibga, pbgl, pbgh);
|
||||
base[i] = blend(base[i], ibga, pbg);
|
||||
}
|
||||
} else {
|
||||
//narrow/wide glyph.
|
||||
for(uint32_t j = 0; j < dh; j++) {
|
||||
uint32_t dataword = fontdata[p.second + (dy + j) / (32 / p.first)];
|
||||
uint32_t* base = scr.rowptr(cy + j) + cx;
|
||||
uint16_t* base = scr.rowptr(cy + j) + cx;
|
||||
for(uint32_t i = 0; i < dw; i++)
|
||||
if(((dataword >> (31 - ((dy + j) % (32 / p.first)) * p.first - (dx + i))) & 1))
|
||||
base[i] = blend(base[i], ifga, pfgl, pfgh);
|
||||
base[i] = blend(base[i], ifga, pfg);
|
||||
else
|
||||
base[i] = blend(base[i], ibga, pbgl, pbgh);
|
||||
base[i] = blend(base[i], ibga, pbg);
|
||||
}
|
||||
}
|
||||
x = next_x;
|
||||
|
@ -221,11 +227,12 @@ render_queue::~render_queue() throw()
|
|||
clear();
|
||||
}
|
||||
|
||||
uint32_t screen::make_color(uint8_t r, uint8_t g, uint8_t b) throw()
|
||||
uint16_t screen::make_color(uint8_t r, uint8_t g, uint8_t b) throw()
|
||||
{
|
||||
return (static_cast<uint32_t>(r) << active_rshift) |
|
||||
(static_cast<uint32_t>(g) << active_gshift) |
|
||||
(static_cast<uint32_t>(b) << active_bshift);
|
||||
uint16_t _r = r / 8;
|
||||
uint16_t _g = g / 8;
|
||||
uint16_t _b = b / 8;
|
||||
return (_r << 10) + (_g << 5) + _b;
|
||||
}
|
||||
|
||||
lcscreen::lcscreen(const uint16_t* mem, bool hires, bool interlace, bool overscan, bool region) throw()
|
||||
|
@ -371,19 +378,19 @@ 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, 2 * width);
|
||||
}
|
||||
for(uint32_t y = 0; y < copyable_height; y++) {
|
||||
uint32_t line = y * vscale + originy;
|
||||
uint32_t* ptr = rowptr(line) + originx;
|
||||
uint16_t* ptr = rowptr(line) + originx;
|
||||
const uint16_t* sbase = scr.memory + y * scr.pitch;
|
||||
for(uint32_t x = 0; x < copyable_width; x++) {
|
||||
uint32_t c = palette[sbase[x] % 32768];
|
||||
uint16_t c = sbase[x] % 32768;
|
||||
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, 2 * hscale * copyable_width);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -404,12 +411,12 @@ void screen::reallocate(uint32_t _width, uint32_t _height, uint32_t _originx, ui
|
|||
flipped = upside_down;
|
||||
return;
|
||||
}
|
||||
uint32_t* newmem = new uint32_t[_width * _height];
|
||||
uint16_t* newmem = new uint16_t[_width * _height];
|
||||
width = _width;
|
||||
height = _height;
|
||||
originx = _originx;
|
||||
originy = _originy;
|
||||
pitch = 4 * _width;
|
||||
pitch = 2 * _width;
|
||||
if(memory && !user_memory)
|
||||
delete[] memory;
|
||||
memory = newmem;
|
||||
|
@ -417,7 +424,7 @@ void screen::reallocate(uint32_t _width, uint32_t _height, uint32_t _originx, ui
|
|||
flipped = upside_down;
|
||||
}
|
||||
|
||||
void screen::set(uint32_t* _memory, uint32_t _width, uint32_t _height, uint32_t _originx, uint32_t _originy,
|
||||
void screen::set(uint16_t* _memory, uint32_t _width, uint32_t _height, uint32_t _originx, uint32_t _originy,
|
||||
uint32_t _pitch) throw()
|
||||
{
|
||||
if(memory && !user_memory)
|
||||
|
@ -432,23 +439,19 @@ void screen::set(uint32_t* _memory, uint32_t _width, uint32_t _height, uint32_t
|
|||
flipped = false;
|
||||
}
|
||||
|
||||
uint32_t* screen::rowptr(uint32_t row) throw()
|
||||
uint16_t* screen::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<uint16_t*>(reinterpret_cast<uint8_t*>(memory) + row * pitch);
|
||||
}
|
||||
|
||||
screen::screen() throw()
|
||||
{
|
||||
uint32_t _magic = 403703808;
|
||||
uint8_t* magic = reinterpret_cast<uint8_t*>(&_magic);
|
||||
memory = NULL;
|
||||
width = height = originx = originy = pitch = 0;
|
||||
user_memory = false;
|
||||
flipped = false;
|
||||
active_rshift = active_gshift = active_bshift = 255;
|
||||
set_palette(magic[0], magic[1], magic[2]);
|
||||
}
|
||||
|
||||
screen::~screen() throw()
|
||||
|
@ -456,35 +459,3 @@ screen::~screen() throw()
|
|||
if(memory && !user_memory)
|
||||
delete[] memory;
|
||||
}
|
||||
|
||||
void screen::set_palette(uint32_t rshift, uint32_t gshift, uint32_t bshift) throw()
|
||||
{
|
||||
if(rshift == active_rshift && gshift == active_gshift && bshift == active_bshift)
|
||||
return;
|
||||
uint32_t old_rshift = active_rshift;
|
||||
uint32_t old_gshift = active_gshift;
|
||||
uint32_t old_bshift = active_bshift;
|
||||
uint32_t xpalette[32];
|
||||
for(unsigned i = 0; i < 32; i++)
|
||||
xpalette[i] = (i * 255 / 31);
|
||||
for(unsigned i = 0; i < 32768; i++) {
|
||||
palette[i] = (xpalette[(i >> 10) & 31] << rshift) +
|
||||
(xpalette[(i >> 5) & 31] << gshift) +
|
||||
(xpalette[i & 31] << bshift);
|
||||
}
|
||||
active_rshift = rshift;
|
||||
active_gshift = gshift;
|
||||
active_bshift = bshift;
|
||||
//Convert the data.
|
||||
for(uint32_t j = 0; j < height; j++) {
|
||||
uint32_t* rp = rowptr(j);
|
||||
for(uint32_t i = 0; i < width; i++) {
|
||||
uint32_t x = rp[i];
|
||||
uint32_t r = (x >> old_rshift) & 0xFF;
|
||||
uint32_t g = (x >> old_gshift) & 0xFF;
|
||||
uint32_t b = (x >> old_bshift) & 0xFF;
|
||||
x = (r << active_rshift) | (g << active_gshift) | (b << active_bshift);
|
||||
rp[i] = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ struct lcscreen
|
|||
};
|
||||
|
||||
/**
|
||||
* Truecolor modifiable screen.
|
||||
* Hicolor modifiable screen.
|
||||
*/
|
||||
struct screen
|
||||
{
|
||||
|
@ -139,7 +139,7 @@ struct screen
|
|||
* parameter _originy: Y coordinate for origin.
|
||||
* parameter _pitch: Distance in bytes between successive scanlines.
|
||||
*/
|
||||
void set(uint32_t* _memory, uint32_t _width, uint32_t _height, uint32_t _originx, uint32_t _originy,
|
||||
void set(uint16_t* _memory, uint32_t _width, uint32_t _height, uint32_t _originx, uint32_t _originy,
|
||||
uint32_t _pitch) throw();
|
||||
|
||||
/**
|
||||
|
@ -170,12 +170,12 @@ struct screen
|
|||
*
|
||||
* parameter row: Number of row (must be less than height).
|
||||
*/
|
||||
uint32_t* rowptr(uint32_t row) throw();
|
||||
uint16_t* rowptr(uint32_t row) throw();
|
||||
|
||||
/**
|
||||
* Backing memory for this screen.
|
||||
*/
|
||||
uint32_t* memory;
|
||||
uint16_t* memory;
|
||||
|
||||
/**
|
||||
* True if memory is given by user and must not be freed.
|
||||
|
@ -212,20 +212,6 @@ struct screen
|
|||
*/
|
||||
uint32_t originy;
|
||||
|
||||
/**
|
||||
* Palette.
|
||||
*/
|
||||
uint32_t palette[32768];
|
||||
|
||||
/**
|
||||
* Sets the palette shifts, converting the existing image.
|
||||
*
|
||||
* parameter rshift Shift for red component.
|
||||
* parameter gshift Shift for green component.
|
||||
* parameter bshift Shift for blue component.
|
||||
*/
|
||||
void set_palette(uint32_t rshift, uint32_t gshift, uint32_t bshift) throw();
|
||||
|
||||
/**
|
||||
* Returns color value with specified (r,g,b) values (scale 0-255).
|
||||
*
|
||||
|
@ -234,22 +220,7 @@ struct screen
|
|||
* parameter b: Blue component.
|
||||
* returns: color element value.
|
||||
*/
|
||||
uint32_t make_color(uint8_t r, uint8_t g, uint8_t b) throw();
|
||||
|
||||
/**
|
||||
* Current red component shift.
|
||||
*/
|
||||
uint32_t active_rshift;
|
||||
|
||||
/**
|
||||
* Current green component shift.
|
||||
*/
|
||||
uint32_t active_gshift;
|
||||
|
||||
/**
|
||||
* Current blue component shift.
|
||||
*/
|
||||
uint32_t active_bshift;
|
||||
uint16_t make_color(uint8_t r, uint8_t g, uint8_t b) throw();
|
||||
private:
|
||||
screen(const screen&);
|
||||
screen& operator=(const screen&);
|
||||
|
@ -327,12 +298,12 @@ std::pair<uint32_t, size_t> find_glyph(uint32_t codepoint, int32_t x, int32_t y,
|
|||
* parameter _y: The y position to render to (relative to origin).
|
||||
* parameter _text: The text to render (UTF-8).
|
||||
* parameter _fg: Foreground color.
|
||||
* parameter _fgalpha: Foreground alpha (0-256).
|
||||
* parameter _fgalpha: Foreground alpha (0-32).
|
||||
* parameter _bg: Background color.
|
||||
* parameter _bgalpha: Background alpha (0-256).
|
||||
* parameter _bgalpha: Background alpha (0-32).
|
||||
* throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
void render_text(struct screen& scr, int32_t _x, int32_t _y, const std::string& _text, uint32_t _fg = 0xFFFFFFFFU,
|
||||
uint16_t _fgalpha = 255, uint32_t _bg = 0, uint16_t _bgalpha = 0) throw(std::bad_alloc);
|
||||
void render_text(struct screen& scr, int32_t _x, int32_t _y, const std::string& _text, uint16_t _fg = 0xFFFFFFFFU,
|
||||
uint8_t _fgalpha = 255, uint16_t _bg = 0, uint8_t _bgalpha = 0) throw(std::bad_alloc);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -12,10 +12,7 @@ namespace
|
|||
return 0;
|
||||
lua_pushnumber(LS, lua_render_ctx->width);
|
||||
lua_pushnumber(LS, lua_render_ctx->height);
|
||||
lua_pushnumber(LS, lua_render_ctx->rshift);
|
||||
lua_pushnumber(LS, lua_render_ctx->gshift);
|
||||
lua_pushnumber(LS, lua_render_ctx->bshift);
|
||||
return 5;
|
||||
return 2;
|
||||
}
|
||||
} gui_resolution;
|
||||
|
||||
|
|
|
@ -5,22 +5,22 @@ namespace
|
|||
{
|
||||
struct render_object_text : public render_object
|
||||
{
|
||||
render_object_text(int32_t _x, int32_t _y, const std::string& _text, uint32_t _fg = 0xFFFFFFFFU,
|
||||
uint16_t _fgalpha = 255, uint32_t _bg = 0, uint16_t _bgalpha = 0) throw(std::bad_alloc);
|
||||
render_object_text(int32_t _x, int32_t _y, const std::string& _text, uint16_t _fg = 0x7FFFU,
|
||||
uint8_t _fgalpha = 32, uint16_t _bg = 0, uint8_t _bgalpha = 0) throw(std::bad_alloc);
|
||||
~render_object_text() throw();
|
||||
void operator()(struct screen& scr) throw();
|
||||
private:
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
uint32_t fg;
|
||||
uint16_t fgalpha;
|
||||
uint32_t bg;
|
||||
uint16_t bgalpha;
|
||||
uint16_t fg;
|
||||
uint8_t fgalpha;
|
||||
uint16_t bg;
|
||||
uint8_t bgalpha;
|
||||
std::string text;
|
||||
};
|
||||
|
||||
render_object_text::render_object_text(int32_t _x, int32_t _y, const std::string& _text, uint32_t _fg,
|
||||
uint16_t _fgalpha, uint32_t _bg, uint16_t _bgalpha) throw(std::bad_alloc)
|
||||
render_object_text::render_object_text(int32_t _x, int32_t _y, const std::string& _text, uint16_t _fg,
|
||||
uint8_t _fgalpha, uint16_t _bg, uint8_t _bgalpha) throw(std::bad_alloc)
|
||||
: x(_x), y(_y), fg(_fg), fgalpha(_fgalpha), bg(_bg), bgalpha(_bgalpha), text(_text)
|
||||
{
|
||||
}
|
||||
|
@ -37,11 +37,9 @@ namespace
|
|||
function_ptr_luafun gui_text("gui.text", [](lua_State* LS, const std::string& fname) -> int {
|
||||
if(!lua_render_ctx)
|
||||
return 0;
|
||||
uint32_t x255 = 255;
|
||||
uint32_t fgc = (x255 << lua_render_ctx->rshift) | (x255 << lua_render_ctx->gshift) |
|
||||
(x255 << lua_render_ctx->bshift);
|
||||
uint32_t fgc = 0x7FFFU;
|
||||
uint32_t bgc = 0;
|
||||
uint16_t fga = 256;
|
||||
uint16_t fga = 32;
|
||||
uint16_t bga = 0;
|
||||
int32_t _x = get_numeric_argument<int32_t>(LS, 1, fname.c_str());
|
||||
int32_t _y = get_numeric_argument<int32_t>(LS, 2, fname.c_str());
|
||||
|
|
|
@ -1760,7 +1760,7 @@ gui.resolution()
|
|||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Returns 5-tuple (hresolution, vresolution, rshift, gshift, bshift).
|
||||
Returns 2-tuple (hresolution, vresolution).
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
|
@ -1793,13 +1793,17 @@ Use gui.resolution() to discover how to layout colors.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Alpha range is 0(transparent)-256(opaque).
|
||||
Alpha range is 0(transparent)-32(opaque).
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Only available in on_paint() and on_video() callbacks.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Colors are 15 bits (1024 * r + 32 * g + b).
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
gui.repaint()
|
||||
\end_layout
|
||||
|
|
Loading…
Add table
Reference in a new issue