std::unique_ptr<os::Viewport> gr_opengl_create_viewport(const os::ViewPortProperties& props) { os::ViewPortProperties attrs = props; attrs.pixel_format.red_size = Gr_red.bits; attrs.pixel_format.green_size = Gr_green.bits; attrs.pixel_format.blue_size = Gr_blue.bits; attrs.pixel_format.alpha_size = (gr_screen.bits_per_pixel == 32) ? Gr_alpha.bits : 0; attrs.pixel_format.depth_size = (gr_screen.bits_per_pixel == 32) ? 24 : 16; attrs.pixel_format.stencil_size = (gr_screen.bits_per_pixel == 32) ? 8 : 1; attrs.pixel_format.multi_samples = os_config_read_uint(NULL, "OGL_AntiAliasSamples", 0); attrs.enable_opengl = true; attrs.gl_attributes.profile = os::OpenGLProfile::Core; return graphic_operations->createViewport(attrs); }
float RocketRenderingInterface::GetPixelsPerInch() { #if SDL_VERSION_ATLEAST(2, 0, 4) auto display = os_config_read_uint("Video", "Display", 0); float ddpi; if (SDL_GetDisplayDPI(display, &ddpi, nullptr, nullptr) != 0) { mprintf(("Failed to determine display DPI: %s\n", SDL_GetError())); return 96.f; } // Diagonal DPI should be accurate enough return ddpi; #else // return a default value return 96.f; #endif }
std::unique_ptr<os::OpenGLContext> SDLGraphicsOperations::createOpenGLContext(const os::OpenGLContextAttributes& attrs, uint32_t width, uint32_t height) { mprintf((" Initializing SDL video...\n")); #ifdef SCP_UNIX // Slight hack to make Mesa advertise S3TC support without libtxc_dxtn setenv("force_s3tc_enable", "true", 1); #endif if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) { Error(LOCATION, "Couldn't init SDL video: %s", SDL_GetError()); return nullptr; } SDL_GL_SetAttribute(SDL_GL_RED_SIZE, attrs.red_size); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, attrs.green_size); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, attrs.blue_size); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, attrs.depth_size); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, attrs.stencil_size); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (attrs.multi_samples == 0) ? 0 : 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, attrs.multi_samples); mprintf((" Requested SDL Video values = R: %d, G: %d, B: %d, depth: %d, stencil: %d, double-buffer: %d, FSAA: %d\n", attrs.red_size, attrs.green_size, attrs.blue_size, attrs.depth_size, attrs.stencil_size, 1, attrs.multi_samples)); uint32_t windowflags = SDL_WINDOW_OPENGL; if (Cmdline_fullscreen_window) { windowflags |= SDL_WINDOW_BORDERLESS; } uint display = os_config_read_uint("Video", "Display", 0); SDL_Window* window = SDL_CreateWindow(Osreg_title, SDL_WINDOWPOS_CENTERED_DISPLAY(display), SDL_WINDOWPOS_CENTERED_DISPLAY(display), width, height, windowflags); if (window == nullptr) { Error(LOCATION, "Could not create window: %s\n", SDL_GetError()); return nullptr; } os_set_window(window); auto ctx = SDL_GL_CreateContext(os_get_window()); if (ctx == nullptr) { Error(LOCATION, "Could not create OpenGL Context: %s\n", SDL_GetError()); return nullptr; } int r, g, b, depth, stencil, db, fsaa_samples; SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &r); SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &g); SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &b); SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depth); SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &db); SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil); SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &fsaa_samples); mprintf((" Actual SDL Video values = R: %d, G: %d, B: %d, depth: %d, stencil: %d, double-buffer: %d, FSAA: %d\n", r, g, b, depth, stencil, db, fsaa_samples)); return std::unique_ptr<os::OpenGLContext>(new SDLOpenGLContext(ctx)); }
// compare version against the passed version file // returns -1 on error // 0 if we are an earlier version // 1 if same version // 2 if higher version // fills in user version and latest version values if non-NULL int version_compare(const char *filename, int *u_major, int *u_minor, int *u_build, int *l_major, int *l_minor, int *l_build) { int usr_major, usr_minor, usr_build; int latest_major, latest_minor, latest_build; // open file and try backup, if needed FILE *f = fopen(filename, "rt"); if (f == NULL) { return -1; } // grab the last line in file which isn't empty and isn't a comment char buffer[MAX_LINE_LENGTH+1], verbuffer[MAX_LINE_LENGTH+1]; strcpy(verbuffer,""); strcpy(buffer,""); while ( !feof(f) ) { // Read the line into a temporary buffer fgets(buffer, MAX_LINE_LENGTH, f); // take the \n off the end of it if (strlen(buffer)>0 && buffer[strlen(buffer) - 1] == '\n') buffer[strlen(buffer) - 1] = 0; // If the line is empty, go get another one if (strlen(buffer) == 0) continue; // If the line is a comment, go get another one if (buffer[0] == VERSION_FILE_COMMENT_CHAR) continue; // Line is a good one, so save it... strcpy(verbuffer, buffer); } fclose(f); // Make sure a version line was found if (strlen(verbuffer) == 0) { // MessageBox(XSTR("Couldn't parse Version file!", 1205), XSTR("Error!", 1185), MB_OK|MB_ICONERROR); return -1; } // Get the most up to date Version number latest_major = 0; latest_minor = 0; latest_build = 0; if (sscanf(verbuffer, "%i %i %i", &latest_major, &latest_minor, &latest_build) != 3) { // MessageBox(XSTR("Couldn't parse Version file!", 1205), XSTR("Error!", 1185), MB_OK|MB_ICONERROR); return -1; } // retrieve the user's current version usr_major = os_config_read_uint("Version", "Major", 0); usr_minor = os_config_read_uint("Version", "Minor", 0); usr_build = os_config_read_uint("Version", "Build", 0); // Make sure the user's Version was found! if ( VER(usr_major, usr_minor, usr_build) == 0 ) { // MessageBox(XSTR("The Freespace 2 Auto-Update program could not find your current game Version in the system registry.\n\nThis should be corrected by starting up the game, exiting the game, and then running the Auto-Update program.", 1206), XSTR("Unable to Determine User's Version", 1207), MB_OK|MB_ICONERROR); return NO_VERSION_IN_REGISTRY; } // stuff outgoing values if(u_major != NULL){ *u_major = usr_major; } if(u_minor != NULL){ *u_minor = usr_minor; } if(u_build != NULL){ *u_build = usr_build; } if(l_major != NULL){ *l_major = latest_major; } if(l_minor != NULL){ *l_minor = latest_minor; } if(l_build != NULL){ *l_build = latest_build; } // check to see if the user's version is up to date if (VER(usr_major, usr_minor, usr_build) < VER(latest_major, latest_minor, latest_build)) { return 0; } // same version return 1; }
int opengl_init_display_device() { int bpp = gr_screen.bits_per_pixel; Assertion((bpp == 16) || (bpp == 32), "Invalid bits-per-pixel value %d!", bpp); // screen format switch (bpp) { case 16: { Gr_red.bits = 5; Gr_red.shift = 11; Gr_red.scale = 8; Gr_red.mask = 0xF800; Gr_green.bits = 6; Gr_green.shift = 5; Gr_green.scale = 4; Gr_green.mask = 0x7E0; Gr_blue.bits = 5; Gr_blue.shift = 0; Gr_blue.scale = 8; Gr_blue.mask = 0x1F; break; } case 32: { Gr_red.bits = 8; Gr_red.shift = 16; Gr_red.scale = 1; Gr_red.mask = 0xff0000; Gr_green.bits = 8; Gr_green.shift = 8; Gr_green.scale = 1; Gr_green.mask = 0x00ff00; Gr_blue.bits = 8; Gr_blue.shift = 0; Gr_blue.scale = 1; Gr_blue.mask = 0x0000ff; Gr_alpha.bits = 8; Gr_alpha.shift = 24; Gr_alpha.mask = 0xff000000; Gr_alpha.scale = 1; break; } } // texture format Gr_t_red.bits = 5; Gr_t_red.mask = 0x7c00; Gr_t_red.shift = 10; Gr_t_red.scale = 8; Gr_t_green.bits = 5; Gr_t_green.mask = 0x03e0; Gr_t_green.shift = 5; Gr_t_green.scale = 8; Gr_t_blue.bits = 5; Gr_t_blue.mask = 0x001f; Gr_t_blue.shift = 0; Gr_t_blue.scale = 8; Gr_t_alpha.bits = 1; Gr_t_alpha.mask = 0x8000; Gr_t_alpha.scale = 255; Gr_t_alpha.shift = 15; // alpha-texture format Gr_ta_red.bits = 4; Gr_ta_red.mask = 0x0f00; Gr_ta_red.shift = 8; Gr_ta_red.scale = 17; Gr_ta_green.bits = 4; Gr_ta_green.mask = 0x00f0; Gr_ta_green.shift = 4; Gr_ta_green.scale = 17; Gr_ta_blue.bits = 4; Gr_ta_blue.mask = 0x000f; Gr_ta_blue.shift = 0; Gr_ta_blue.scale = 17; Gr_ta_alpha.bits = 4; Gr_ta_alpha.mask = 0xf000; Gr_ta_alpha.shift = 12; Gr_ta_alpha.scale = 17; // allocate storage for original gamma settings if ( !Cmdline_no_set_gamma && (GL_original_gamma_ramp == NULL) ) { GL_original_gamma_ramp = (ushort*) vm_malloc( 3 * 256 * sizeof(ushort), memory::quiet_alloc); if (GL_original_gamma_ramp == NULL) { mprintf((" Unable to allocate memory for gamma ramp! Disabling...\n")); Cmdline_no_set_gamma = 1; } else { // assume identity ramp by default, to be overwritten by true ramp later for (ushort x = 0; x < 256; x++) { GL_original_gamma_ramp[x] = GL_original_gamma_ramp[x + 256] = GL_original_gamma_ramp[x + 512] = (x << 8) | x; } } } os::ViewPortProperties attrs; attrs.enable_opengl = true; attrs.gl_attributes.major_version = MIN_REQUIRED_GL_VERSION / 10; attrs.gl_attributes.minor_version = MIN_REQUIRED_GL_VERSION % 10; #ifndef NDEBUG attrs.gl_attributes.flags.set(os::OpenGLContextFlags::Debug); #endif attrs.gl_attributes.profile = os::OpenGLProfile::Core; attrs.display = os_config_read_uint("Video", "Display", 0); attrs.width = (uint32_t) gr_screen.max_w; attrs.height = (uint32_t) gr_screen.max_h; attrs.title = Osreg_title; if (!Cmdline_window && ! Cmdline_fullscreen_window) { attrs.flags.set(os::ViewPortFlags::Fullscreen); } else if (Cmdline_fullscreen_window) { attrs.flags.set(os::ViewPortFlags::Borderless); } auto viewport = gr_opengl_create_viewport(attrs); if (!viewport) { return 1; } const int gl_versions[] = { 45, 44, 43, 42, 41, 40, 33, 32 }; // find the latest and greatest OpenGL context for (auto ver : gl_versions) { auto gl_attrs = attrs.gl_attributes; gl_attrs.major_version = ver / 10; gl_attrs.minor_version = ver % 10; GL_context = graphic_operations->createOpenGLContext(viewport.get(), gl_attrs); if (GL_context != nullptr) { break; } } if (GL_context == nullptr) { return 1; } auto port = os::addViewport(std::move(viewport)); os::setMainViewPort(port); // We can't use gr_use_viewport because that tries to use OpenGL which hasn't been initialized yet graphic_operations->makeOpenGLContextCurrent(port, GL_context.get()); current_viewport = port; if (GL_original_gamma_ramp != NULL && os::getSDLMainWindow() != nullptr) { SDL_GetWindowGammaRamp( os::getSDLMainWindow(), GL_original_gamma_ramp, (GL_original_gamma_ramp+256), (GL_original_gamma_ramp+512) ); } return 0; }
int joy_init() { int i, n; if (Joy_inited) return 0; if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) { mprintf(("Could not initialize joystick\n")); return 0; } // enable event processing of the joystick if ( (SDL_JoystickEventState(SDL_ENABLE)) != SDL_ENABLE ) { mprintf(("ERROR: Unable to initialize joystick event processing!\n")); SDL_QuitSubSystem(SDL_INIT_JOYSTICK); return 0; } n = SDL_NumJoysticks(); if (n < 1) { mprintf(("No joysticks found\n")); SDL_QuitSubSystem(SDL_INIT_JOYSTICK); return 0; } joy_get_caps(n); Cur_joystick = os_config_read_uint(NULL, "CurrentJoystick", JOYSTICKID1); sdljoy = SDL_JoystickOpen(Cur_joystick); if (sdljoy == NULL) { mprintf(("Unable to init joystick %d\n", Cur_joystick)); SDL_QuitSubSystem(SDL_INIT_JOYSTICK); return 0; } joy_flush(); joy_num_sticks = n; joy_num_buttons = SDL_JoystickNumButtons(sdljoy); joy_num_axes = SDL_JoystickNumAxes(sdljoy); joy_num_hats = SDL_JoystickNumHats(sdljoy); mprintf(( "\nJoystick INITTED!\n\n" )); mprintf(( "Using '%s' as the primary joystick:\n", SDL_JoystickName(SDL_JoystickOpen(Cur_joystick)) )); mprintf(( " Number of axes: %i\n", joy_num_axes )); mprintf(( " Number of buttons: %i\n", joy_num_buttons )); mprintf(( " Number of hats: %i\n", joy_num_hats )); mprintf(( " Number of trackballs: %i\n\n", SDL_JoystickNumBalls(sdljoy) )); // Fake a calibration if (joy_num_sticks > 0) { for (i=0; i<JOY_NUM_AXES; i++) { joystick.axis_center[i] = 32768; joystick.axis_min[i] = 0; joystick.axis_max[i] = 65536; } } // we poll for axis type motion so be sure to ignore that during normal event state polling SDL_EventState( SDL_JOYAXISMOTION, SDL_IGNORE ); SDL_EventState( SDL_JOYBALLMOTION, SDL_IGNORE ); // we do want to make sure that hat/button presses go through event polling though // (should be on by default already, just here as a reminder) SDL_EventState( SDL_JOYBUTTONDOWN, SDL_ENABLE ); SDL_EventState( SDL_JOYBUTTONUP, SDL_ENABLE ); SDL_EventState( SDL_JOYHATMOTION, SDL_ENABLE ); Joy_inited = 1; return joy_num_sticks; }
void multi_options_read_config() { CFILE *in; char str[512]; char *tok = NULL; // set default value for the global multi options Multi_options_g.reset(); ushort forced_port = (ushort)os_config_read_uint(NULL, "ForcePort", 0); Multi_options_g.port = (Cmdline_network_port >= 0) ? (ushort)Cmdline_network_port : forced_port == 0 ? (ushort)DEFAULT_GAME_PORT : forced_port; Multi_options_g.log = (Cmdline_multi_log) ? 1 : 0; // read in the config file in = cfopen(MULTI_CFG_FILE, "rt", CFILE_NORMAL, CF_TYPE_DATA); // if we failed to open the config file, user default settings if (in == NULL) { nprintf(("Network","Failed to open network config file, using default settings\n")); } else { while ( !cfeof(in) ) { // read in the game info memset(str, 0, 512); cfgets(str, 512, in); // parse the first line tok = strtok(str, " \t"); // check the token if (tok != NULL) { drop_leading_white_space(tok); drop_trailing_white_space(tok); } else { continue; } // all possible options // only standalone cares about the following options if (Is_standalone) { // setup PXO mode if ( SETTING("+pxo") ) { NEXT_TOKEN(); if (tok != NULL) { strncpy(Multi_fs_tracker_channel, tok, MAX_PATH-1); } } else // set the standalone server's permanent name if ( SETTING("+name") ) { NEXT_TOKEN(); if (tok != NULL) { strncpy(Multi_options_g.std_pname, tok, STD_NAME_LEN); } } else // standalone won't allow voice transmission if ( SETTING("+no_voice") ) { Multi_options_g.std_voice = 0; } else // set the max # of players on the standalone if ( SETTING("+max_players") ) { NEXT_TOKEN(); if (tok != NULL) { if ( !((atoi(tok) < 1) || (atoi(tok) > MAX_PLAYERS)) ) { Multi_options_g.std_max_players = atoi(tok); } } } else // ban a player if ( SETTING("+ban") ) { NEXT_TOKEN(); if (tok != NULL) { std_add_ban(tok); } } else // set the standalone host password if ( SETTING("+passwd") ) { NEXT_TOKEN(); if (tok != NULL) { strncpy(Multi_options_g.std_passwd, tok, STD_PASSWD_LEN); #ifdef _WIN32 // yuck extern HWND Multi_std_host_passwd; SetWindowText(Multi_std_host_passwd, Multi_options_g.std_passwd); #else // TODO: get password ? // argh, gonna have to figure out how to do this - mharris 07/07/2002 #endif } } else // set standalone to low updates if ( SETTING("+low_update") ) { Multi_options_g.std_datarate = OBJ_UPDATE_LOW; } else // set standalone to medium updates if ( SETTING("+med_update") ) { Multi_options_g.std_datarate = OBJ_UPDATE_MEDIUM; } else // set standalone to high updates if ( SETTING("+high_update") ) { Multi_options_g.std_datarate = OBJ_UPDATE_HIGH; } else // set standalone to high updates if ( SETTING("+lan_update") ) { Multi_options_g.std_datarate = OBJ_UPDATE_LAN; } else // use pxo flag if ( SETTING("+use_pxo") ) { Om_tracker_flag = 1; } else // standalone pxo login user if ( SETTING("+pxo_login") ) { NEXT_TOKEN(); if (tok != NULL) { strncpy(Multi_options_g.std_pxo_login, tok, MULTI_TRACKER_STRING_LEN); } } else // standalone pxo login password if ( SETTING("+pxo_password") ) { NEXT_TOKEN(); if (tok != NULL) { strncpy(Multi_options_g.std_pxo_password, tok, MULTI_TRACKER_STRING_LEN); } } else if ( SETTING("+webui_root") ) { NEXT_TOKEN(); if (tok != NULL) { Multi_options_g.webuiRootDirectory = SCP_string(tok); } } else if ( SETTING("+webapi_username") ) { NEXT_TOKEN(); if (tok != NULL) { Multi_options_g.webapiUsername = SCP_string(tok); } } else if ( SETTING("+webapi_password") ) { NEXT_TOKEN(); if (tok != NULL) { Multi_options_g.webapiPassword = SCP_string(tok); } } else if ( SETTING("+webapi_server_port") ) { NEXT_TOKEN(); if (tok != NULL) { long int result = strtol(tok, NULL, 10); if(result <= 0 || result > USHRT_MAX) { mprintf(("ERROR: Invalid or out of range webapi_server_port '%s' specified in multi.cfg, must be integer between 1024 and %i.\n", tok, USHRT_MAX)); } else if(result < 1024) { mprintf(("ERROR: webapi_server_port '%ld' in multi.cfg is too low, must be between 1024 and %d.\n", result, USHRT_MAX)); } else { mprintf(("Using webapi_server_port '%ld' from multi.cfg.\n", result)); Multi_options_g.webapiPort = (ushort) result; } } } } // ... common to all modes ... // ip addr of user tracker if ( SETTING("+user_server") ) { NEXT_TOKEN(); if (tok != NULL) { strcpy_s(Multi_options_g.user_tracker_ip, tok); } } else // ip addr of game tracker if ( SETTING("+game_server") ) { NEXT_TOKEN(); if (tok != NULL) { strcpy_s(Multi_options_g.game_tracker_ip, tok); } } else // port to use for the game/user tracker (FS2NetD) if ( SETTING("+server_port") ) { NEXT_TOKEN(); if (tok != NULL) { strcpy_s(Multi_options_g.tracker_port, tok); } } else // ip addr of pxo chat server if ( SETTING("+chat_server") ) { NEXT_TOKEN(); if (tok != NULL) { strcpy_s(Multi_options_g.pxo_ip, tok); } } else // url of pilot rankings page if ( SETTING("+rank_url") ) { NEXT_TOKEN(); if (tok != NULL) { strcpy_s(Multi_options_g.pxo_rank_url, tok); } } else // url of pxo account create page if ( SETTING("+create_url") ) { NEXT_TOKEN(); if (tok != NULL) { strcpy_s(Multi_options_g.pxo_create_url, tok); } } else // url of pxo account verify page if ( SETTING("+verify_url") ) { NEXT_TOKEN(); if (tok != NULL) { strcpy_s(Multi_options_g.pxo_verify_url, tok); } } else // url of pxo banners if ( SETTING("+banner_url") ) { NEXT_TOKEN(); if (tok != NULL) { strcpy_s(Multi_options_g.pxo_banner_url, tok); } } else // set the max datarate for high updates if ( SETTING("+datarate") ) { NEXT_TOKEN(); if (tok != NULL) { if ( atoi(tok) >= 4000 ) { Multi_options_g.datarate_cap = atoi(tok); } } } else // get the proxy server if ( SETTING("+http_proxy") ) { NEXT_TOKEN(); if (tok != NULL) { char *ip = strtok(tok, ":"); if (ip != NULL) { strcpy_s(Multi_options_proxy, ip); } ip = strtok(NULL, ""); if (ip != NULL) { Multi_options_proxy_port = (ushort)atoi(ip); } else { strcpy_s(Multi_options_proxy, ""); } } } } // close the config file cfclose(in); in = NULL; } #ifndef _WIN32 if (Is_standalone) { std_configLoaded(&Multi_options_g); } #endif }