コード例 #1
0
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);
}
コード例 #2
0
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
}
コード例 #3
0
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));
}
コード例 #4
0
ファイル: version.cpp プロジェクト: lubomyr/freespace2
// 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;
}
コード例 #5
0
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;
}
コード例 #6
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;
}
コード例 #7
0
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
}