void CL_InputSource_File::open() { if (filehandle != NULL) return; #ifndef WIN32 // hate win32 non posix conform if (filename[0] == '!') { filehandle = popen(std::string(filename, 1).c_str(), "rb"); if (filehandle == NULL) { throw CL_Error("Could not open pipe: " + std::string(filename,1)); } filesize = 99999999; } else #endif { filename = translate_path(filename); filehandle = fopen(filename.c_str(), "rb"); if (filehandle == NULL) { std::cout << "Error: Could not open file: " << filename << std::endl; throw CL_Error("Could not open file: " + filename); } fseek(filehandle, 0, SEEK_END); filesize = ftell(filehandle); fseek(filehandle, 0, SEEK_SET); } // cl_assert(filehandle != NULL); }
void CL_PNGProvider_Generic::init() { //setting up PNGLIB stuff png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) throw CL_Error ("CL_PNGProvider_Generic: png_create_read_struct() failed"); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); throw CL_Error ("CL_PNGProvider_Generic: png_create_info_struct() failed"); } end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); cl_assert(false); } if (setjmp(png_ptr->jmpbuf)) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); cl_assert(false); } cl_assert(provider != NULL); input_source = provider->open_source(filename); cl_assert(input_source!=NULL); // tell libpng form whom it get the fileData png_set_read_fn(png_ptr, this, &CL_PNGProvider_Generic::pngread_file); // reading the header infos and actually read data ... read_data(); // remove our data_provider from libpng png_set_read_fn(png_ptr,NULL,NULL); // free memory ... png_destroy_read_struct(&png_ptr, &info_ptr,&end_info); delete input_source; // this could be integrated better, but I'm too tired, so I just hack CL_PixelBuffer // support into it. -- mbn 21. feb 2002 CL_PixelBuffer_Generic::format.enable_colorkey(uses_src_colorkey()); CL_PixelBuffer_Generic::format.set_colorkey(get_src_colorkey()); CL_PixelBuffer_Generic::pitch = get_pitch(); CL_PixelBuffer_Generic::width = get_width(); CL_PixelBuffer_Generic::height = get_height(); if (is_indexed()) CL_PixelBuffer_Generic::format.set_type(pixelformat_index); }
Game::Game(std::string nameFirstPlayer, std::string nameSecondPlayer) : playingTime(0), bMustQuitGame(false) { Game::instance = this; srand((unsigned) time(NULL)); try { resourceManager = new CL_ResourceManager("resources.xml"); font[0] = new CL_Font("Game/font36", resourceManager); font[1] = new CL_Font("Game/font58", resourceManager); font[2] = new CL_Font("Game/font100", resourceManager); } catch(CL_Error err) { throw CL_Error(err.message); } viewpoint = new CL_Viewpoint(); framerateCounter = new CL_FramerateCounter(); world = new World(resourceManager, 200, 200, 200); CL_Mouse::hide(); players = new std::list<Player*>(); players->clear(); if(nameFirstPlayer != "") { Player *p1 = new HumanPlayer(FIRST, 20.0, 20.0, 4.0, nameFirstPlayer); players->push_back(p1); setupViewpoint(p1->getSide()); } else { throw CL_Error("Le nom du premier joueur (nameFirstPlayer) n'est pas specifie."); } if(nameSecondPlayer != "") { players->push_back(new HumanPlayer(SECOND, 20.0, 20.0, 4.0, nameSecondPlayer)); } else { players->push_back(new AIPlayer(SECOND, 20.0, 20.0, 4.0)); } projectile = new LocalProjectile(5.0); //initialisation de l'intro manager IntroManager::getInstance(); this->initDisplay(); }
void CL_OutputSource_File::open() { if(file != NULL) return; file = fopen(filename.c_str(), "w+b"); if(file == NULL) throw CL_Error("could not create file"); }
void CL_Texture::set_size( int format, int width, int height, int depth, int border, int level) { switch (impl->target) { case CL_TEXTURE_3D: set_image3d_gl( impl->target, level, format, width, height, depth, border, CL_RGBA, CL_BYTE, 0); break; case CL_TEXTURE_2D: set_image2d_gl( impl->target, level, format, width, height, border, CL_RGBA, CL_BYTE, 0); break; case CL_TEXTURE_1D: set_image2d_gl( impl->target, level, format, width, border, CL_RGBA, CL_BYTE, 0); break; default: throw CL_Error("CL_Texture::set_image does not support this texture format"); } }
void CL_ResourceData_TextStyler::on_load() { CL_Resource resource = get_resource(); CL_ResourceManager manager = resource.get_manager(); ts = CL_TextStyler(); std::map<std::string, CL_Font>& fnt_map = ts.get_fonts(); for ( CL_DomNode cur_node = resource.get_element().get_first_child(); !cur_node.is_null(); cur_node = cur_node.get_next_sibling()) { if (!cur_node.is_element()) continue; CL_DomElement cur_element = cur_node.to_element(); if ( cur_element.get_tag_name() == "font" && cur_element.has_attribute("name") && cur_element.has_attribute("font")) { if (manager.exists(cur_element.get_attribute("font"))) { fnt_map[cur_element.get_attribute("name")] = CL_Font(cur_element.get_attribute("font"), &manager); } else { throw CL_Error(std::string("CL_TextStyler: Unable to find sub-font named ") + cur_element.get_attribute("font")); } } else { throw CL_Error("CL_TextStyler: Unknown sub-element of a text_styler resource"); } } }
PlayNode::PlayNode(int levelIndex) { // Cargamos el nivel level = new Level(levelIndex); // Creamos el nodo del mapa mapNode = new MapNode(this); // Creamos el nodo del inventario inventoryNode = new InventoryNode(); // Comprobamos que todo ha ido bien if ( !level || !mapNode || !inventoryNode ) { throw CL_Error("Error: PlayNode::PlayNode"); } }
void CL_PNGProvider_Generic::read_data() { // initial fileinfo png_read_info(png_ptr, info_ptr); // reduce 16bit/channel to 8Bit/channel png_set_strip_16(png_ptr); // reread infostruct to reflect the made settings png_read_update_info(png_ptr, info_ptr); width = png_get_image_width(png_ptr,info_ptr); height = png_get_image_height(png_ptr,info_ptr); color_type = png_get_color_type(png_ptr,info_ptr); switch (color_type) { case PNG_COLOR_TYPE_GRAY: read_data_grayscale (); break; case PNG_COLOR_TYPE_GRAY_ALPHA: read_data_grayscale_alpha (); break; case PNG_COLOR_TYPE_PALETTE: read_data_palette (); break; case PNG_COLOR_TYPE_RGB: read_data_rgb (); break; case PNG_COLOR_TYPE_RGB_ALPHA: read_data_rgba (); break; default: throw CL_Error ("CL_PNGProvider_Generic: Unsupported PNG format!"); break; } }
std::string CL_InputSource_File::translate_path(const std::string &path) { int len = 0; // try to figure out if path is absolute. if (path.length() > 0 && (path[0] == '\\' || path[0] == '/' || (path.length() > 1 && path[1] == ':'))) { // path is absolute return path; } else { //note, I moved BigZaphod's mac path hack to Application/MacOS/clanapp.cpp -mrfun may 18 2006 char cwd[1026]; if (getcwd(cwd, 1024) == NULL) throw CL_Error("Working dir is more than 1024 characters!"); len = strlen(cwd); if (cwd[len-1] != '/' && cwd[len-1] != '\\') strcat(cwd, "/"); return std::string(cwd) + std::string(path); } }
void CL_Texture::set_cube_map( CL_PixelBuffer &cube_map_positive_x, CL_PixelBuffer &cube_map_negative_x, CL_PixelBuffer &cube_map_positive_y, CL_PixelBuffer &cube_map_negative_y, CL_PixelBuffer &cube_map_positive_z, CL_PixelBuffer &cube_map_negative_z, int level, int border, int format) { if (impl->target != CL_TEXTURE_CUBE_MAP) throw CL_Error("CL_Texture::set_cube_map does not support this texture format"); CL_PixelBuffer cube_maps[6]; cube_maps[0] = cube_map_positive_x; cube_maps[1] = cube_map_negative_x; cube_maps[2] = cube_map_positive_y; cube_maps[3] = cube_map_negative_y; cube_maps[4] = cube_map_positive_z; cube_maps[5] = cube_map_negative_z; CLenum native_format[6]; CLenum native_type[6]; int index_maps; // Make sure our images are in opengl compatible formats: for (index_maps = 0; index_maps < 6; index_maps++) { bool is_native_format = CL_OpenGL::to_opengl_pixelformat( cube_maps[index_maps].get_format(), native_format[index_maps], native_type[index_maps]); if (!is_native_format) { cube_maps[index_maps] = cube_maps[index_maps].to_format(CL_PixelFormat::rgba8888); is_native_format = CL_OpenGL::to_opengl_pixelformat( cube_maps[index_maps].get_format(), native_format[index_maps], native_type[index_maps]); } } // Upload cube maps: int targets[6] = { CL_TEXTURE_CUBE_MAP_POSITIVE_X, CL_TEXTURE_CUBE_MAP_NEGATIVE_X, CL_TEXTURE_CUBE_MAP_POSITIVE_Y, CL_TEXTURE_CUBE_MAP_NEGATIVE_Y, CL_TEXTURE_CUBE_MAP_POSITIVE_Z, CL_TEXTURE_CUBE_MAP_NEGATIVE_Z }; for (index_maps = 0; index_maps < 6; index_maps++) { cube_maps[index_maps].lock(); set_image2d_gl( targets[index_maps], level, (format == 0) ? native_format[index_maps] : format, cube_maps[index_maps].get_width(), cube_maps[index_maps].get_height(), border, native_format[index_maps], native_type[index_maps], cube_maps[index_maps].get_data()); cube_maps[index_maps].unlock(); } }
void CL_Texture::set_image( CL_PixelBuffer &image, int level, int border, int format) { CLenum native_format = 0, native_type = 0; bool is_native_format = CL_OpenGL::to_opengl_pixelformat(image.get_format(), native_format, native_type); if (is_native_format) { switch (impl->target) { /* case CL_TEXTURE_3D: image.lock(); set_image3d_gl( impl->target, level, (format == 0) ? native_format : format, image.get_width(), image.get_height(), image.get_depth(), border, native_format, native_type, image.get_data()); image.unlock(); break; */ case CL_TEXTURE_2D: image.lock(); set_image2d_gl( impl->target, level, (format == 0) ? native_format : format, image.get_width(), image.get_height(), border, native_format, native_type, image.get_data()); image.unlock(); break; case CL_TEXTURE_1D: image.lock(); set_image1d_gl( impl->target, level, (format == 0) ? native_format : format, image.get_width(), border, native_format, native_type, image.get_data()); image.unlock(); break; default: throw CL_Error("CL_Texture::set_image does not support this texture format"); } } else { // For now, upload all non-opengl compatible formats in rgba8888 format: CL_PixelBuffer gl_image = image.to_format(CL_PixelFormat::rgba8888); set_image(gl_image, format, level, border); } }
void cl_throw_error(const std::string &message) { throw CL_Error(message); }
void cl_throw_error(const char *message) { throw CL_Error(message); }
void CL_ResourceData_Font::on_load() { CL_Resource resource = get_resource(); CL_ResourceManager manager = resource.get_manager(); CL_DomElement system_element = resource.get_element().named_item("system").to_element(); CL_DomElement bitmap_element = resource.get_element().named_item("bitmap").to_element(); // First check if it's a system font if (!system_element.is_null()) { if (!system_element.has_attribute("height")) throw CL_Error("System font resource " + resource.get_name() + " has no 'height' attribute."); const std::string font_name = system_element.get_attribute("font_name"); const int height = CL_String::to_int(system_element.get_attribute("height")); int width = 0; bool bold = false; bool italic = false; bool underline = false; bool strikeout = false; if (system_element.has_attribute("width")) width = CL_String::to_int(system_element.get_attribute("width")); if (system_element.has_attribute("bold")) bold = (CL_String::to_int(system_element.get_attribute("bold")) != 0); if (system_element.has_attribute("italic")) italic = (CL_String::to_int(system_element.get_attribute("italic")) != 0); if (system_element.has_attribute("underline")) underline = (CL_String::to_int(system_element.get_attribute("underline")) != 0); if (system_element.has_attribute("strikeout")) strikeout = (CL_String::to_int(system_element.get_attribute("strikeout")) != 0); if (system_element.has_attribute("letters")) { font = CL_Font( font_name, system_element.get_attribute("letters"), height, width, bold, italic, underline, strikeout); } else { font = CL_Font( font_name, height, width, bold, italic, underline, strikeout); } } else if (!bitmap_element.is_null()) { if (!bitmap_element.has_attribute("glyphs")) throw CL_Error("Font resource " + resource.get_name() + " has no 'glyphs' attribute."); if (!bitmap_element.has_attribute("letters")) throw CL_Error("Font resource " + resource.get_name() + " has no 'letters' attribute."); //Set most values to CL_Font defaults, then we can override them with options if they exist const CL_Sprite spr_glyphs(bitmap_element.get_attribute("glyphs"), &manager); const std::string letters = bitmap_element.get_attribute("letters"); int spacelen = -1; bool monospace = false; if (bitmap_element.has_attribute("spacelen")) spacelen = CL_String::to_int(bitmap_element.get_attribute("spacelen")); if (bitmap_element.has_attribute("monospace")) monospace = (CL_String::to_int(bitmap_element.get_attribute("monospace")) != 0); font = CL_Font( spr_glyphs, letters, spacelen, monospace); } else { throw CL_Error(CL_String::format("Font resource %1 did not have a <system> or <bitmap> child element!", resource.get_name())); } if (resource.get_element().has_attribute("width_offset")) font.set_width_offset(CL_String::to_int(resource.get_element().get_attribute("width_offset"))); if (resource.get_element().has_attribute("height_offset")) font.set_height_offset(CL_String::to_int(resource.get_element().get_attribute("height_offset"))); if (resource.get_element().has_attribute("delims")) font.set_delims(resource.get_element().get_attribute("delims")); }
void CL_PNGProvider_Generic::read_data_palette() { format.set_type(pixelformat_index); format.set_red_mask(0x00000000); format.set_green_mask(0x00000000); format.set_blue_mask(0x00000000); format.set_alpha_mask(0x00000000); format.set_depth(8); int bit_depth = png_get_bit_depth(png_ptr,info_ptr); int rowbytes = png_get_rowbytes(png_ptr, info_ptr); unsigned char* tmp_image = new unsigned char[height * rowbytes]; // Allocating the temporary buffer (will be deleted some // screens below png_bytep* row_pointers = new png_bytep[height]; { for (int y = 0; y < height; y++) row_pointers[y] = tmp_image + (rowbytes * y); } png_read_image(png_ptr, row_pointers); if (bit_depth == 8) { // We don't need to convert the data, so we can use // what we got image = tmp_image; pitch = rowbytes; } else { // We need to convert the data pitch = width; int y,x; switch (bit_depth) { case 1: image = new unsigned char[height * rowbytes * 8]; for (y = 0; y < height; y++) { for (x = 0; x < rowbytes; x++) { image[y*pitch + 8*x + 0] = row_pointers[y][x] >> 7; image[y*pitch + 8*x + 1] = row_pointers[y][x] >> 6 & 0x1; image[y*pitch + 8*x + 2] = row_pointers[y][x] >> 5 & 0x1; image[y*pitch + 8*x + 3] = row_pointers[y][x] >> 4 & 0x1; image[y*pitch + 8*x + 4] = row_pointers[y][x] >> 3 & 0x1; image[y*pitch + 8*x + 5] = row_pointers[y][x] >> 2 & 0x1; image[y*pitch + 8*x + 6] = row_pointers[y][x] >> 1 & 0x1; image[y*pitch + 8*x + 7] = row_pointers[y][x] & 0x1; } } break; case 2: image = new unsigned char[height * rowbytes * 4]; for (y = 0; y < height; y++) { for (x = 0; x < rowbytes; x++) { image[y*pitch + 4*x + 0] = row_pointers[y][x] >> 6; image[y*pitch + 4*x + 1] = row_pointers[y][x] >> 4 & 0x3; image[y*pitch + 4*x + 2] = row_pointers[y][x] >> 2 & 0x3; image[y*pitch + 4*x + 3] = row_pointers[y][x] & 0x3; } } break; case 4: image = new unsigned char[height * rowbytes * 2]; for (y = 0; y < height; y++) { for (x = 0; x < rowbytes; x++) { image[y*pitch + 2*x + 0] = row_pointers[y][x] >> 4; image[y*pitch + 2*x + 1] = row_pointers[y][x] & 0x0f; } } break; default: throw CL_Error ("CL_PNGProvider_Generic: Unhandled bit depth"); } delete[] tmp_image; } delete[] row_pointers; // Read the png palette and create the CL_Palette int num_colors = 256; png_colorp png_palette; png_get_PLTE(png_ptr, info_ptr, &png_palette, &num_colors); if (num_colors > 256) num_colors = 256; // clanlib currently only support palette sizes of max 256. { for (int k = 0; k < num_colors; k++) palette[k].set_color(png_palette[k].red, png_palette[k].green, png_palette[k].blue); } if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { // Reading and setting up the transparent colors from the image int num_trans = 0; png_color_16p trans_values; png_bytep trans; png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &trans_values); //Trans information exists for each color in the palette, it doesn't mean //that color is actually transparent. We need to check its alpha for that data. //Ideally, we should probably detect if more than one is transparent and convert it to a full //alpha, but that seems like overkill for now. -mrfun for (int i=0; i < num_trans; i++) { if (trans[i] == 0) { trans_col = i; m_uses_src_colorkey = true; break; //we only support one color } } } }
void CL_DisplayWindow_OpenGL::create_window(const CL_DisplayWindowDescription &desc) { const CL_OpenGLWindowDescription_Generic *gl_desc = 0; gl_desc = dynamic_cast<const CL_OpenGLWindowDescription_Generic*>(desc.impl.get()); fullscreen_width = desc.get_size().width; fullscreen_height = desc.get_size().height; XVisualInfo *vi; Colormap cmap; if (disp == 0) { disp = XOpenDisplay(0); if (disp == 0) throw CL_Error("Could not open X11 display!"); } disp_ref_count++; int gl_attribs_single[] = { GLX_RGBA, GLX_RED_SIZE, 4, GLX_GREEN_SIZE, 4, GLX_BLUE_SIZE, 4, GLX_DEPTH_SIZE, 16, None }; int gl_attribs[32]; int i = 0; if( gl_desc ) { if( gl_desc->rgba ) gl_attribs[i++] = GLX_RGBA; if( gl_desc->doublebuffer ) gl_attribs[i++] = GLX_DOUBLEBUFFER; if( gl_desc->stereo ) gl_attribs[i++] = GLX_STEREO; gl_attribs[i++] = GLX_BUFFER_SIZE; gl_attribs[i++] = gl_desc->buffer_size; gl_attribs[i++] = GLX_LEVEL; gl_attribs[i++] = gl_desc->level; gl_attribs[i++] = GLX_AUX_BUFFERS; gl_attribs[i++] = gl_desc->aux_buffers; gl_attribs[i++] = GLX_RED_SIZE; gl_attribs[i++] = gl_desc->red_size; gl_attribs[i++] = GLX_GREEN_SIZE; gl_attribs[i++] = gl_desc->green_size; gl_attribs[i++] = GLX_BLUE_SIZE; gl_attribs[i++] = gl_desc->blue_size; gl_attribs[i++] = GLX_DEPTH_SIZE; gl_attribs[i++] = gl_desc->depth_size; gl_attribs[i++] = GLX_STENCIL_SIZE; gl_attribs[i++] = gl_desc->stencil_size; gl_attribs[i++] = GLX_ACCUM_RED_SIZE; gl_attribs[i++] = gl_desc->accum_red_size; gl_attribs[i++] = GLX_ACCUM_GREEN_SIZE; gl_attribs[i++] = gl_desc->accum_green_size; gl_attribs[i++] = GLX_ACCUM_BLUE_SIZE; gl_attribs[i++] = gl_desc->accum_blue_size; gl_attribs[i++] = GLX_ACCUM_ALPHA_SIZE; gl_attribs[i++] = gl_desc->accum_alpha_size; gl_attribs[i++] = GLX_ACCUM_RED_SIZE; gl_attribs[i++] = gl_desc->accum_red_size; gl_attribs[i++] = None; } else { gl_attribs[i++] = GLX_RGBA; gl_attribs[i++] = GLX_DOUBLEBUFFER; gl_attribs[i++] = GLX_RED_SIZE; gl_attribs[i++] = 4; gl_attribs[i++] = GLX_GREEN_SIZE; gl_attribs[i++] = 4; gl_attribs[i++] = GLX_BLUE_SIZE; gl_attribs[i++] = 4; gl_attribs[i++] = GLX_DEPTH_SIZE; gl_attribs[i++] = 16; gl_attribs[i++] = None; } // get an appropriate visual vi = glXChooseVisual(disp, DefaultScreen(disp), gl_attribs); if (vi == NULL) { vi = glXChooseVisual(disp, window, gl_attribs_single); printf("Requested visual not supported by your OpenGL implementation. Falling back on singlebuffered Visual!\n"); } // create a GLX context context = glXCreateContext(disp, vi, share_context, True); if( share_context == NULL ) share_context = context; glXGetConfig(disp, vi, GLX_BUFFER_SIZE, &glx_bpp); // create a color map cmap = XCreateColormap( disp, RootWindow(disp, vi->screen), vi->visual, AllocNone); attributes.colormap = cmap; attributes.border_pixel = 0; attributes.override_redirect = False; // create a window in window mode attributes.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask | FocusChangeMask; window = XCreateWindow(disp, RootWindow(disp, vi->screen), 0, 0, desc.get_size().width, desc.get_size().height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask, &attributes); XSelectInput(disp, window, FocusChangeMask | KeyPressMask | KeyReleaseMask | PropertyChangeMask | StructureNotifyMask | KeymapStateMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask); // set title of window: set_title(desc.get_title()); // setup size hints: XSizeHints size_hints; memset(&size_hints, 0, sizeof(XSizeHints)); size_hints.width = desc.get_size().width; size_hints.height = desc.get_size().height; size_hints.base_width = desc.get_size().width; size_hints.base_height = desc.get_size().height; size_hints.min_width = size_hints.width; size_hints.min_height = size_hints.height; size_hints.max_width = size_hints.width; size_hints.max_height = size_hints.height; size_hints.flags = PSize|PBaseSize; if (!desc.get_allow_resize()) size_hints.flags |= PMinSize | PMaxSize; XSetWMNormalHints(disp, window, &size_hints); // handle wm_delete_events if in windowed mode: Atom wm_delete = XInternAtom(disp, "WM_DELETE_WINDOW", True); XSetWMProtocols(disp, window, &wm_delete, 1); // make window visible: XMapRaised(disp, window); if (!glXIsDirect(disp, context)) printf("No hardware acceleration available. I hope you got a really fast machine..\n"); // Create input devices for window: keyboard = CL_InputDevice(new CL_InputDevice_X11Keyboard(this)); mouse = CL_InputDevice(new CL_InputDevice_X11Mouse(this)); get_ic()->clear(); get_ic()->add_keyboard(keyboard); get_ic()->add_mouse(mouse); setup_joysticks(); // setup_usb_mice(); // setup_xinput(); // setup_event(); XSync(disp, True); focus = true; system_cursor = XCreateFontCursor(disp, XC_left_ptr); char *data = (char*)malloc(64); // 8x8 memset(data, 0, 64); XColor black_color; memset(&black_color, 0, sizeof(black_color)); cursor_bitmap = XCreateBitmapFromData(disp, window, data, 8, 8); hidden_cursor = XCreatePixmapCursor(disp, cursor_bitmap, cursor_bitmap, &black_color, &black_color, 0,0 ); if (desc.is_fullscreen()) set_fullscreen(desc.get_size().width, desc.get_size().height, desc.get_bpp(), desc.get_refresh_rate()); }