static char *CheckDirectoryHasIWAD(char *dir, char *iwadname) { char *filename; // As a special case, the "directory" may refer directly to an // IWAD file if the path comes from DOOMWADDIR or DOOMWADPATH. if (DirIsFile(dir, iwadname) && M_FileExists(dir)) { return M_StringDuplicate(dir); } // Construct the full path to the IWAD if it is located in // this directory, and check if it exists. if (!strcmp(dir, ".")) { filename = M_StringDuplicate(iwadname); } else { filename = M_StringJoin(dir, DIR_SEPARATOR_S, iwadname, NULL); } if (M_FileExists(filename)) { return filename; } free(filename); return NULL; }
// Add IWAD directories parsed from splitting a path string containing // paths separated by PATH_SEPARATOR. 'suffix' is a string to concatenate // to the end of the paths before adding them. static void AddIWADPath(char *path, char *suffix) { char *left, *p; path = M_StringDuplicate(path); // Split into individual dirs within the list. left = path; for (;;) { p = strchr(left, PATH_SEPARATOR); if (p != NULL) { // Break at the separator and use the left hand side // as another iwad dir *p = '\0'; AddIWADDir(M_StringJoin(left, suffix, NULL)); left = p + 1; } else { break; } } AddIWADDir(M_StringJoin(left, suffix, NULL)); free(path); }
void SetChatMacroDefaults(void) { int i; const char *const defaults[] = { HUSTR_CHATMACRO0, HUSTR_CHATMACRO1, HUSTR_CHATMACRO2, HUSTR_CHATMACRO3, HUSTR_CHATMACRO4, HUSTR_CHATMACRO5, HUSTR_CHATMACRO6, HUSTR_CHATMACRO7, HUSTR_CHATMACRO8, HUSTR_CHATMACRO9, }; // If the chat macros have not been set, initialize with defaults. for (i=0; i<10; ++i) { if (chat_macros[i] == NULL) { chat_macros[i] = M_StringDuplicate(defaults[i]); } } }
static void D_SetDefaultSavePath(void) { SavePath = M_GetSaveGameDir("hexen.wad"); if (!strcmp(SavePath, "")) { // only get hexen.cfg path if one is not already found if (!strcmp(SavePathConfig, "")) { // If we are not using a savegame path (probably because we are on // Windows and not using a config dir), behave like Vanilla Hexen // and use hexndata/: SavePath = malloc(10); M_snprintf(SavePath, 10, "hexndata%c", DIR_SEPARATOR); } else { SavePath = M_StringDuplicate(SavePathConfig); } } // only set hexen.cfg path if using default handling if (!M_ParmExists("-savedir") && !M_ParmExists("-cdrom")) { SavePathConfig = SavePath; } }
void SetPlayerNameDefault(void) { if (net_player_name == NULL) { net_player_name = getenv("USER"); } if (net_player_name == NULL) { net_player_name = getenv("USERNAME"); } if (net_player_name == NULL) { net_player_name = "player"; } // Now strdup() the string so that it's in a mutable form // that can be freed when the value changes. #ifdef _WIN32 // On Windows, environment variables are in OEM codepage // encoding, so convert to UTF8: net_player_name = M_OEMToUTF8(net_player_name); #else net_player_name = M_StringDuplicate(net_player_name); #endif }
static void SelectQueryAddress(TXT_UNCAST_ARG(button), TXT_UNCAST_ARG(querydata)) { TXT_CAST_ARG(txt_button_t, button); TXT_CAST_ARG(net_querydata_t, querydata); int i; if (querydata->server_state != 0) { TXT_MessageBox("Cannot connect to server", "Gameplay is already in progress\n" "on this server."); return; } // Set address to connect to: free(connect_address); connect_address = M_StringDuplicate(button->label); // Auto-choose IWAD if there is already a player connected. if (querydata->num_players > 0) { for (i = 0; found_iwads[i] != NULL; ++i) { if (found_iwads[i]->mode == querydata->gamemode && found_iwads[i]->mission == querydata->gamemission) { found_iwad_selected = i; iwadfile = found_iwads[i]->name; break; } } if (found_iwads[i] == NULL) { TXT_MessageBox(NULL, "The game on this server seems to be:\n" "\n" " %s\n" "\n" "but the IWAD file %s is not found!\n" "Without the required IWAD file, it may not be\n" "possible to join this game.", D_SuggestGameName(querydata->gamemission, querydata->gamemode), D_SuggestIWADName(querydata->gamemission, querydata->gamemode)); } } // Finished with search. TXT_CloseWindow(query_window); }
// [crispy] portable pendant to libgen.h's dirname() // does not modify its argument char *M_DirName(char *path) { char *src, *res; res = M_StringDuplicate(path); src = res + strlen(res) - 1; while (src != res) { if (*src == DIR_SEPARATOR) { *src = '\0'; return res; } src--; } // path string does not contain a directory separator free(res); return M_StringDuplicate("."); }
deh_context_t *DEH_OpenFile(char *filename) { FILE *fstream; deh_context_t *context; fstream = fopen(filename, "r"); if (fstream == NULL) return NULL; context = DEH_NewContext(); context->type = DEH_INPUT_FILE; context->stream = fstream; context->filename = M_StringDuplicate(filename); return context; }
char *D_FindWADByName(char *name) { char *path; int i; // Absolute path? if (M_FileExists(name)) { return name; } BuildIWADDirList(); // Search through all IWAD paths for a file with the given name. for (i=0; i<num_iwad_dirs; ++i) { // As a special case, if this is in DOOMWADDIR or DOOMWADPATH, // the "directory" may actually refer directly to an IWAD // file. if (DirIsFile(iwad_dirs[i], name) && M_FileExists(iwad_dirs[i])) { return M_StringDuplicate(iwad_dirs[i]); } // Construct a string for the full path path = M_StringJoin(iwad_dirs[i], DIR_SEPARATOR_S, name, NULL); if (M_FileExists(path)) { return path; } free(path); } // File not found return NULL; }
static void ParseLine(gus_config_t *config, char *line) { char *fields[6]; unsigned int num_fields; unsigned int instr_id, mapped_id; num_fields = SplitLine(line, fields, 6); if (num_fields < 6) { return; } instr_id = atoi(fields[0]); mapped_id = atoi(fields[MappingIndex()]); free(config->patch_names[instr_id]); config->patch_names[instr_id] = M_StringDuplicate(fields[5]); config->mapping[instr_id] = mapped_id; }
static void NET_SV_InitNewClient(net_client_t *client, net_addr_t *addr, char *player_name) { client->active = true; client->connect_time = I_GetTimeMS(); NET_Conn_InitServer(&client->connection, addr); client->addr = addr; client->last_send_time = -1; client->name = M_StringDuplicate(player_name); // init the ticcmd send queue client->sendseq = 0; client->acknowledged = 0; client->drone = false; client->ready = false; client->last_gamedata_time = 0; memset(client->sendqueue, 0xff, sizeof(client->sendqueue)); }
static wad_file_t *W_StdC_OpenFile(const char *path) { stdc_wad_file_t *result; FILE *fstream; fstream = fopen(path, "rb"); if (fstream == NULL) { return NULL; } // Create a new stdc_wad_file_t to hold the file handle. result = Z_Malloc(sizeof(stdc_wad_file_t), PU_STATIC, 0); result->wad.file_class = &stdc_wad_file; result->wad.mapped = NULL; result->wad.length = M_FileLength(fstream); result->wad.path = M_StringDuplicate(path); result->fstream = fstream; return &result->wad; }
void G_LoadGame(char *name) { savename = M_StringDuplicate(name); gameaction = ga_loadgame; }
void BindSoundVariables(void) { M_BindIntVariable("snd_sfxdevice", &snd_sfxdevice); M_BindIntVariable("snd_musicdevice", &snd_musicdevice); M_BindIntVariable("snd_channels", &numChannels); M_BindIntVariable("snd_samplerate", &snd_samplerate); M_BindIntVariable("sfx_volume", &sfxVolume); M_BindIntVariable("music_volume", &musicVolume); M_BindIntVariable("use_libsamplerate", &use_libsamplerate); M_BindFloatVariable("libsamplerate_scale", &libsamplerate_scale); M_BindIntVariable("gus_ram_kb", &gus_ram_kb); M_BindStringVariable("gus_patch_path", &gus_patch_path); M_BindStringVariable("music_pack_path", &music_pack_path); M_BindStringVariable("timidity_cfg_path", &timidity_cfg_path); M_BindIntVariable("snd_sbport", &snd_sbport); M_BindIntVariable("snd_sbirq", &snd_sbirq); M_BindIntVariable("snd_sbdma", &snd_sbdma); M_BindIntVariable("snd_mport", &snd_mport); M_BindIntVariable("snd_maxslicetime_ms", &snd_maxslicetime_ms); M_BindStringVariable("snd_musiccmd", &snd_musiccmd); M_BindStringVariable("snd_dmxoption", &snd_dmxoption); M_BindIntVariable("snd_cachesize", &snd_cachesize); M_BindIntVariable("opl_io_port", &opl_io_port); M_BindIntVariable("snd_pitchshift", &snd_pitchshift); if (gamemission == strife) { M_BindIntVariable("voice_volume", &voiceVolume); M_BindIntVariable("show_talk", &show_talk); } music_pack_path = M_StringDuplicate(""); timidity_cfg_path = M_StringDuplicate(""); gus_patch_path = M_StringDuplicate(""); // All versions of Heretic and Hexen did pitch-shifting. // Most versions of Doom did not and Strife never did. snd_pitchshift = gamemission == heretic || gamemission == hexen; // Default sound volumes - different games use different values. switch (gamemission) { case doom: default: sfxVolume = 8; musicVolume = 8; break; case heretic: case hexen: sfxVolume = 10; musicVolume = 10; break; case strife: sfxVolume = 8; musicVolume = 13; break; } }
void BindSoundVariables(void) { M_BindIntVariable("snd_sfxdevice", &snd_sfxdevice); M_BindIntVariable("snd_musicdevice", &snd_musicdevice); M_BindIntVariable("snd_channels", &numChannels); M_BindIntVariable("snd_samplerate", &snd_samplerate); M_BindIntVariable("sfx_volume", &sfxVolume); M_BindIntVariable("music_volume", &musicVolume); M_BindIntVariable("use_libsamplerate", &use_libsamplerate); M_BindFloatVariable("libsamplerate_scale", &libsamplerate_scale); M_BindIntVariable("gus_ram_kb", &gus_ram_kb); M_BindStringVariable("gus_patch_path", &gus_patch_path); M_BindStringVariable("timidity_cfg_path", &timidity_cfg_path); M_BindIntVariable("snd_sbport", &snd_sbport); M_BindIntVariable("snd_sbirq", &snd_sbirq); M_BindIntVariable("snd_sbdma", &snd_sbdma); M_BindIntVariable("snd_mport", &snd_mport); M_BindIntVariable("snd_maxslicetime_ms", &snd_maxslicetime_ms); M_BindStringVariable("snd_musiccmd", &snd_musiccmd); M_BindStringVariable("snd_dmxoption", &snd_dmxoption); M_BindIntVariable("snd_cachesize", &snd_cachesize); M_BindIntVariable("opl_io_port", &opl_io_port); M_BindIntVariable("snd_pitchshift", &snd_pitchshift); if (gamemission == strife) { M_BindIntVariable("voice_volume", &voiceVolume); M_BindIntVariable("show_talk", &show_talk); } timidity_cfg_path = M_StringDuplicate(""); gus_patch_path = M_StringDuplicate(""); // All versions of Heretic and Hexen did pitch-shifting. // Most versions of Doom did not and Strife never did. snd_pitchshift = gamemission == heretic || gamemission == hexen; // Default sound volumes - different games use different values. switch (gamemission) { case doom: default: sfxVolume = 8; musicVolume = 8; break; case heretic: case hexen: sfxVolume = 10; musicVolume = 10; break; case strife: sfxVolume = 8; musicVolume = 13; break; } // Before SDL_mixer version 1.2.11, MIDI music caused the game // to crash when it looped. If this is an old SDL_mixer version, // disable MIDI. #ifdef __MACOSX__ { const SDL_version *v = Mix_Linked_Version(); if (SDL_VERSIONNUM(v->major, v->minor, v->patch) < SDL_VERSIONNUM(1, 2, 11)) { snd_musicdevice = SNDDEVICE_NONE; } } #endif }
// Load dehacked patches needed for certain IWADs. static void LoadIwadDeh(void) { // The Freedoom IWADs have DEHACKED lumps that must be loaded. if (W_CheckNumForName("FREEDOOM") >= 0) { // Old versions of Freedoom (before 2014-09) did not have technically // valid DEHACKED lumps, so ignore errors and just continue if this // is an old IWAD. DEH_LoadLumpByName("DEHACKED", false, true); } // If this is the HACX IWAD, we need to load the DEHACKED lump. if (gameversion == exe_hacx) { if (!DEH_LoadLumpByName("DEHACKED", true, false)) { I_Error("DEHACKED lump not found. Please check that this is the " "Hacx v1.2 IWAD."); } } // Chex Quest needs a separate Dehacked patch which must be downloaded // and installed next to the IWAD. if (gameversion == exe_chex) { char *chex_deh = NULL; char *sep; // Look for chex.deh in the same directory as the IWAD file. sep = strrchr(iwadfile, DIR_SEPARATOR); if (sep != NULL) { size_t chex_deh_len = strlen(iwadfile) + 9; chex_deh = malloc(chex_deh_len); M_StringCopy(chex_deh, iwadfile, chex_deh_len); chex_deh[sep - iwadfile + 1] = '\0'; M_StringConcat(chex_deh, "chex.deh", chex_deh_len); } else { chex_deh = M_StringDuplicate("chex.deh"); } // If the dehacked patch isn't found, try searching the WAD // search path instead. We might find it... if (!M_FileExists(chex_deh)) { free(chex_deh); chex_deh = D_FindWADByName("chex.deh"); } // Still not found? if (chex_deh == NULL) { I_Error("Unable to find Chex Quest dehacked file (chex.deh).\n" "The dehacked file is required in order to emulate\n" "chex.exe correctly. It can be found in your nearest\n" "/idgames repository mirror at:\n\n" " utils/exe_edit/patches/chexdeh.zip"); } if (!DEH_LoadFile(chex_deh)) { I_Error("Failed to load chex.deh needed for emulating chex.exe."); } } }
glob_t *I_StartMultiGlob(const char *directory, int flags, const char *glob, ...) { char **globs; int num_globs; glob_t *result; va_list args; globs = malloc(sizeof(char *)); if (globs == NULL) { return NULL; } globs[0] = M_StringDuplicate(glob); num_globs = 1; va_start(args, glob); for (;;) { const char *arg = va_arg(args, const char *); char **new_globs; if (arg == NULL) { break; } new_globs = realloc(globs, sizeof(char *) * (num_globs + 1)); if (new_globs == NULL) { FreeStringList(globs, num_globs); } globs = new_globs; globs[num_globs] = M_StringDuplicate(arg); ++num_globs; } va_end(args); result = malloc(sizeof(glob_t)); if (result == NULL) { FreeStringList(globs, num_globs); return NULL; } result->dir = opendir(directory); if (result->dir == NULL) { FreeStringList(globs, num_globs); free(result); return NULL; } result->directory = M_StringDuplicate(directory); result->globs = globs; result->num_globs = num_globs; result->flags = flags; result->last_filename = NULL; result->filenames = NULL; result->filenames_len = 0; result->next_index = -1; return result; }
// // M_LoadCVARs // void M_LoadCVARs(char *filename) { int bindcount = 0; int cvarcount = 0; int statcount = 0; // read the file in, overriding any set defaults FILE *file = fopen(filename, "r"); if (!file) { M_CheckCVARs(); M_SaveCVARs(); C_Output("Created <b>%s</b>.", filename); cvarsloaded = true; return; } for (int i = 0; i < MAXALIASES; i++) { aliases[i].name[0] = '\0'; aliases[i].string[0] = '\0'; } // Clear all default controls before reading them from config file if (!togglingvanilla && M_StringEndsWith(filename, PACKAGE_CONFIG)) { for (int i = 0; *actions[i].action; i++) { if (actions[i].keyboard1) *(int *)actions[i].keyboard1 = 0; if (actions[i].keyboard2) *(int *)actions[i].keyboard2 = 0; if (actions[i].mouse1) *(int *)actions[i].mouse1 = -1; if (actions[i].gamepad1) *(int *)actions[i].gamepad1 = 0; if (actions[i].gamepad2) *(int *)actions[i].gamepad2 = 0; } for (int i = 0; i < NUMKEYS; i++) keyactionlist[i][0] = '\0'; } while (!feof(file)) { char cvar[64] = ""; char value[256] = ""; if (fscanf(file, "%63s %255[^\n]\n", cvar, value) != 2) continue; if (cvar[0] == ';') continue; if (M_StringCompare(cvar, "bind")) { bind_cmd_func2("bind", value); bindcount++; continue; } else if (M_StringCompare(cvar, "alias")) { if (!togglingvanilla) alias_cmd_func2("alias", value); continue; } // Strip off trailing non-printable characters (\r characters from DOS text files) while (*value && !isprint((unsigned char)value[strlen(value) - 1])) value[strlen(value) - 1] = '\0'; if (togglingvanilla) { char *value_free = uncommify(value); C_ValidateInput(M_StringJoin(cvar, " ", value_free, NULL)); free(value_free); continue; } // Find the setting in the list for (int i = 0; i < arrlen(cvars); i++) { char *s; if (!M_StringCompare(cvar, cvars[i].name)) continue; // not this one if (M_StringStartsWith(cvar, "stat_")) statcount++; else cvarcount++; // parameter found switch (cvars[i].type) { case DEFAULT_STRING: s = M_StringDuplicate(value + 1); s[strlen(s) - 1] = '\0'; *(char **)cvars[i].location = s; break; case DEFAULT_INT: { char *value_free = uncommify(value); M_StringCopy(value, value_free, sizeof(value)); *(int *)cvars[i].location = ParseIntParameter(value, cvars[i].valuealiastype); free(value_free); break; } case DEFAULT_INT_UNSIGNED: { char *value_free = uncommify(value); M_StringCopy(value, value_free, sizeof(value)); sscanf(value, "%10u", (unsigned int *)cvars[i].location); free(value_free); break; } case DEFAULT_INT_PERCENT: { char *value_free = uncommify(value); M_StringCopy(value, value_free, sizeof(value)); s = M_StringDuplicate(value); if (*s && s[strlen(s) - 1] == '%') s[strlen(s) - 1] = '\0'; *(int *)cvars[i].location = ParseIntParameter(s, cvars[i].valuealiastype); free(value_free); break; } case DEFAULT_FLOAT: { char *value_free = uncommify(value); M_StringCopy(value, value_free, sizeof(value)); *(float *)cvars[i].location = ParseFloatParameter(value, cvars[i].valuealiastype); free(value_free); break; } case DEFAULT_FLOAT_PERCENT: { char *value_free = uncommify(value); M_StringCopy(value, value_free, sizeof(value)); s = M_StringDuplicate(value); if (*s && s[strlen(s) - 1] == '%') s[strlen(s) - 1] = '\0'; *(float *)cvars[i].location = ParseFloatParameter(s, cvars[i].valuealiastype); free(value_free); break; } case DEFAULT_OTHER: *(char **)cvars[i].location = M_StringDuplicate(value); break; } // finish break; } } fclose(file); if (!togglingvanilla) { char *cvarcount_str = commify(cvarcount); char *statcount_str = commify(statcount); char *bindcount_str = commify(bindcount); C_Output("Loaded %s CVARs and %s player stats from <b>%s</b>.", cvarcount_str, statcount_str, filename); C_Output("Bound %s actions to the keyboard, mouse and gamepad.", bindcount_str); M_CheckCVARs(); cvarsloaded = true; free(cvarcount_str); free(statcount_str); free(bindcount_str); } }
static void M_CheckCVARs(void) { if (alwaysrun != false && alwaysrun != true) alwaysrun = alwaysrun_default; if (am_allmapcdwallcolor < am_allmapcdwallcolor_min || am_allmapcdwallcolor > am_allmapcdwallcolor_max) am_allmapcdwallcolor = am_allmapcdwallcolor_default; if (am_allmapfdwallcolor < am_allmapfdwallcolor_min || am_allmapfdwallcolor > am_allmapfdwallcolor_max) am_allmapfdwallcolor = am_allmapfdwallcolor_default; if (am_allmapwallcolor < am_allmapwallcolor_min || am_allmapwallcolor > am_allmapwallcolor_max) am_allmapwallcolor = am_allmapwallcolor_default; if (am_backcolor < am_backcolor_min || am_backcolor > am_backcolor_max) am_backcolor = am_backcolor_default; if (am_cdwallcolor < am_cdwallcolor_min || am_cdwallcolor > am_cdwallcolor_max) am_cdwallcolor = am_cdwallcolor_default; if (am_crosshaircolor < am_crosshaircolor_min || am_crosshaircolor > am_crosshaircolor_max) am_crosshaircolor = am_crosshaircolor_default; if (am_external != false && am_external != true) am_external = am_external_default; if (am_fdwallcolor < am_fdwallcolor_min || am_fdwallcolor > am_fdwallcolor_max) am_fdwallcolor = am_fdwallcolor_default; if (am_grid != false && am_grid != true) am_grid = am_grid_default; if (am_gridcolor < am_gridcolor_min || am_gridcolor > am_gridcolor_max) am_gridcolor = am_gridcolor_default; if (am_markcolor < am_markcolor_min || am_markcolor > am_markcolor_max) am_markcolor = am_markcolor_default; if (am_path != false && am_path != true) am_path = am_path_default; if (am_pathcolor < am_pathcolor_min || am_pathcolor > am_pathcolor_max) am_pathcolor = am_pathcolor_default; if (am_playercolor < am_playercolor_min || am_playercolor > am_playercolor_max) am_playercolor = am_playercolor_default; if (am_rotatemode != false && am_rotatemode != true) am_rotatemode = am_rotatemode_default; if (am_teleportercolor < am_teleportercolor_min || am_teleportercolor > am_teleportercolor_max) am_teleportercolor = am_teleportercolor_default; if (am_thingcolor < am_thingcolor_min || am_thingcolor > am_thingcolor_max) am_thingcolor = am_thingcolor_default; if (am_tswallcolor < am_tswallcolor_min || am_tswallcolor > am_tswallcolor_max) am_tswallcolor = am_tswallcolor_default; if (am_wallcolor < am_wallcolor_min || am_wallcolor > am_wallcolor_max) am_wallcolor = am_wallcolor_default; if (autoaim != false && autoaim != true) autoaim = autoaim_default; if (autoload != false && autoload != true) autoload = autoload_default; if (autotilt != false && autotilt != true) autotilt = autotilt_default; if (autouse != false && autouse != true) autouse = autouse_default; if (centerweapon != false && centerweapon != true) centerweapon = centerweapon_default; if (con_backcolor < con_backcolor_min || con_backcolor > con_backcolor_max) con_backcolor = con_backcolor_default; if (con_obituaries != false && con_obituaries != true) con_obituaries = con_obituaries_default; if (con_timestamps != false && con_timestamps != true) con_timestamps = con_timestamps_default; if (crosshair != crosshair_none && crosshair != crosshair_cross && crosshair != crosshair_dot) crosshair = crosshair_default; if (crosshaircolor < crosshaircolor_min || crosshaircolor > crosshaircolor_max) crosshaircolor = crosshaircolor_default; episode = BETWEEN(episode_min, episode, episode_max); expansion = BETWEEN(expansion_min, expansion, expansion_max); if (facebackcolor < facebackcolor_min || facebackcolor > facebackcolor_max) facebackcolor = facebackcolor_default; if (gp_analog != false && gp_analog != true) gp_analog = gp_analog_default; gp_deadzone_left = BETWEENF(gp_deadzone_left_min, gp_deadzone_left, gp_deadzone_left_max); I_SetGamepadLeftDeadZone(); gp_deadzone_right = BETWEENF(gp_deadzone_right_min, gp_deadzone_right, gp_deadzone_right_max); I_SetGamepadRightDeadZone(); if (gp_invertyaxis != false && gp_invertyaxis != true) gp_invertyaxis = gp_invertyaxis_default; gp_sensitivity = BETWEEN(gp_sensitivity_min, gp_sensitivity, gp_sensitivity_max); I_SetGamepadSensitivity(); if (gp_swapthumbsticks != false && gp_swapthumbsticks != true) gp_swapthumbsticks = gp_swapthumbsticks_default; if (gp_thumbsticks < gp_thumbsticks_min || gp_thumbsticks > gp_thumbsticks_max) gp_thumbsticks = gp_thumbsticks_default; gp_vibrate_barrels = BETWEEN(gp_vibrate_barrels_min, gp_vibrate_barrels, gp_vibrate_barrels_max); gp_vibrate_damage = BETWEEN(gp_vibrate_damage_min, gp_vibrate_damage, gp_vibrate_damage_max); gp_vibrate_weapons = BETWEEN(gp_vibrate_weapons_min, gp_vibrate_damage, gp_vibrate_weapons_max); if (infighting != false && infighting != true) infighting = infighting_default; if (infiniteheight != false && infiniteheight != true) infiniteheight = infiniteheight_default; if (!*iwadfolder || M_StringCompare(iwadfolder, iwadfolder_default) || !M_FolderExists(iwadfolder)) D_InitIWADFolder(); if (m_acceleration != false && m_acceleration != true) m_acceleration = m_acceleration_default; if (m_doubleclick_use != false && m_doubleclick_use != true) m_doubleclick_use = m_doubleclick_use_default; if (m_invertyaxis != false && m_invertyaxis != true) m_invertyaxis = m_invertyaxis_default; if (m_novertical != false && m_novertical != true) m_novertical = m_novertical_default; m_sensitivity = BETWEEN(m_sensitivity_min, m_sensitivity, m_sensitivity_max); if (messages != false && messages != true) messages = messages_default; if (mouselook != false && mouselook != true) mouselook = mouselook_default; movebob = BETWEEN(movebob_min, movebob, movebob_max); if (!*playername) playername = M_StringDuplicate(playername_default); if (r_althud != false && r_althud != true) r_althud = r_althud_default; r_berserkintensity = BETWEEN(r_berserkintensity_min, r_berserkintensity, r_berserkintensity_max); if (r_blood != r_blood_none && r_blood != r_blood_red && r_blood != r_blood_all) r_blood = r_blood_default; r_bloodsplats_max = BETWEEN(r_bloodsplats_max_min, r_bloodsplats_max, r_bloodsplats_max_max); if (r_bloodsplats_translucency != false && r_bloodsplats_translucency != true) r_bloodsplats_translucency = r_bloodsplats_translucency_default; if (r_brightmaps != false && r_brightmaps != true) r_brightmaps = r_brightmaps_default; r_color = BETWEEN(r_color_min, r_color, r_color_max); if (r_corpses_color != false && r_corpses_color != true) r_corpses_color = r_corpses_color_default; if (r_corpses_mirrored != false && r_corpses_mirrored != true) r_corpses_mirrored = r_corpses_mirrored_default; if (r_corpses_moreblood != false && r_corpses_moreblood != true) r_corpses_moreblood = r_corpses_moreblood_default; if (r_corpses_nudge != false && r_corpses_nudge != true) r_corpses_nudge = r_corpses_nudge_default; if (r_corpses_slide != false && r_corpses_slide != true) r_corpses_slide = r_corpses_slide_default; if (r_corpses_smearblood != false && r_corpses_smearblood != true) r_corpses_smearblood = r_corpses_smearblood_default; if (r_detail != r_detail_low && r_detail != r_detail_high) r_detail = r_detail_default; if (r_diskicon != false && r_diskicon != true) r_diskicon = r_diskicon_default; if (r_dither != false && r_dither != true) r_dither = r_dither_default; if (r_fixmaperrors != false && r_fixmaperrors != true) r_fixmaperrors = r_fixmaperrors_default; if (r_fixspriteoffsets != false && r_fixspriteoffsets != true) r_fixspriteoffsets = r_fixspriteoffsets_default; if (r_floatbob != false && r_floatbob != true) r_floatbob = r_floatbob_default; r_fov = BETWEEN(r_fov_min, r_fov, r_fov_max); r_gamma = BETWEENF(r_gamma_min, r_gamma, r_gamma_max); I_SetGamma(r_gamma); if (r_homindicator != false && r_homindicator != true) r_homindicator = r_homindicator_default; if (r_hud != false && r_hud != true) r_hud = r_hud_default; if (r_hud_translucency != false && r_hud_translucency != true) r_hud_translucency = r_hud_translucency_default; if (r_liquid_bob != false && r_liquid_bob != true) r_liquid_bob = r_liquid_bob_default; if (r_liquid_clipsprites != false && r_liquid_clipsprites != true) r_liquid_clipsprites = r_liquid_clipsprites_default; if (r_liquid_current != false && r_liquid_current != true) r_liquid_current = r_liquid_current_default; if (r_liquid_lowerview != false && r_liquid_lowerview != true) r_liquid_lowerview = r_liquid_lowerview_default; if (r_liquid_swirl != false && r_liquid_swirl != true) r_liquid_swirl = r_liquid_swirl_default; if (r_mirroredweapons != false && r_mirroredweapons != true) r_mirroredweapons = r_mirroredweapons_default; if (r_playersprites != false && r_playersprites != true) r_playersprites = r_playersprites_default; if (r_rockettrails != false && r_rockettrails != true) r_rockettrails = r_rockettrails_default; r_screensize = BETWEEN(r_screensize_min, r_screensize, r_screensize_max); if (r_shadows != false && r_shadows != true) r_shadows = r_shadows_default; if (r_shadows_translucency != false && r_shadows_translucency != true) r_shadows_translucency = r_shadows_translucency_default; if (r_shake_barrels != false && r_shake_barrels != true) r_shake_barrels = r_shake_barrels_default; r_shake_damage = BETWEEN(r_shake_damage_min, r_shake_damage, r_shake_damage_max); if (r_skycolor != r_skycolor_none && (r_skycolor < r_skycolor_min || r_skycolor > r_skycolor_max)) r_skycolor = r_skycolor_default; if (r_textures != false && r_textures != true) r_textures = r_textures_default; if (r_translucency != false && r_translucency != true) r_translucency = r_translucency_default; s_channels = BETWEEN(s_channels_min, s_channels, s_channels_max); s_musicvolume = BETWEEN(s_musicvolume_min, s_musicvolume, s_musicvolume_max); musicVolume = (s_musicvolume * 31 + 50) / 100; if (s_randommusic != false && s_randommusic != true) s_randommusic = s_randommusic_default; if (s_randompitch != false && s_randompitch != true) s_randompitch = s_randompitch_default; s_sfxvolume = BETWEEN(s_sfxvolume_min, s_sfxvolume, s_sfxvolume_max); sfxVolume = (s_sfxvolume * 31 + 50) / 100; if (s_stereo != false && s_stereo != true) s_stereo = s_stereo_default; savegame = BETWEEN(savegame_min, savegame, savegame_max); skilllevel = BETWEEN(skilllevel_min, skilllevel, skilllevel_max); stillbob = BETWEEN(stillbob_min, stillbob, stillbob_max); if (tossdrop != false && tossdrop != true) tossdrop = tossdrop_default; turbo = BETWEEN(turbo_min, turbo, turbo_max); if (units != units_imperial && units != units_metric) units = units_default; version = version_default; vid_capfps = BETWEEN(vid_capfps_min, vid_capfps, vid_capfps_max); vid_display = MAX(vid_display_min, vid_display); if (vid_fullscreen != false && vid_fullscreen != true) vid_fullscreen = vid_fullscreen_default; vid_motionblur = BETWEEN(vid_motionblur_min, vid_motionblur, vid_motionblur_max); if (vid_pillarboxes != false && vid_pillarboxes != true) vid_pillarboxes = vid_pillarboxes_default; if (!M_StringCompare(vid_scaleapi, vid_scaleapi_direct3d) #if defined(__MACOSX__) && !M_StringCompare(vid_scaleapi, vid_scaleapi_metal) #endif && !M_StringCompare(vid_scaleapi, vid_scaleapi_opengl) #if !defined(_WIN32) && !M_StringCompare(vid_scaleapi, vid_scaleapi_opengles) && !M_StringCompare(vid_scaleapi, vid_scaleapi_opengles2) #endif && !M_StringCompare(vid_scaleapi, vid_scaleapi_software)) vid_scaleapi = vid_scaleapi_default; if (!M_StringCompare(vid_scalefilter, vid_scalefilter_linear) && !M_StringCompare(vid_scalefilter, vid_scalefilter_nearest) && !M_StringCompare(vid_scalefilter, vid_scalefilter_nearest_linear)) vid_scalefilter = vid_scalefilter_default; if (vid_vsync != false && vid_vsync != true) vid_vsync = vid_vsync_default; if (vid_widescreen != false && vid_widescreen != true) vid_widescreen = vid_widescreen_default; if (vid_widescreen) { returntowidescreen = true; vid_widescreen = false; r_screensize = r_screensize_max; } else r_hud = true; weaponbob = BETWEEN(weaponbob_min, weaponbob, weaponbob_max); if (weaponbounce != false && weaponbounce != true) weaponbounce = weaponbounce_default; if (weaponrecoil != false && weaponrecoil != true) weaponrecoil = weaponrecoil_default; if (wipe != false && wipe != true) wipe = wipe_default; }
static void NET_SV_ParseSYN(net_packet_t *packet, net_client_t *client, net_addr_t *addr) { unsigned int magic; net_connect_data_t data; net_packet_t *reply; net_protocol_t protocol; char *player_name; char *client_version; int num_players; int i; NET_Log("server: processing SYN packet"); // Read the magic number and check it is the expected one. if (!NET_ReadInt32(packet, &magic)) { NET_Log("server: error: no magic number for SYN"); return; } switch (magic) { case NET_MAGIC_NUMBER: break; case NET_OLD_MAGIC_NUMBER: NET_Log("server: error: client using old magic number: %d", magic); NET_SV_SendReject(addr, "You are using an old client version that is not supported by " "this server. This server is running " PACKAGE_STRING "."); return; default: NET_Log("server: error: wrong magic number: %d", magic); return; } // Read the client version string. We actually now only use this when // sending a reject message, as we only reject if we can't negotiate a // common protocol (below). client_version = NET_ReadString(packet); if (client_version == NULL) { NET_Log("server: error: no version from client"); return; } // Read the client's list of accepted protocols. Net play between forks // of Chocolate Doom is accepted provided that they can negotiate a // common accepted protocol. protocol = NET_ReadProtocolList(packet); if (protocol == NET_PROTOCOL_UNKNOWN) { char reject_msg[256]; M_snprintf(reject_msg, sizeof(reject_msg), "Version mismatch: server version is: " PACKAGE_STRING "; " "client is: %s. No common compatible protocol could be " "negotiated.", client_version); NET_SV_SendReject(addr, reject_msg); NET_Log("server: error: no common protocol"); return; } // Read connect data, and check that the game mode/mission are valid // and the max_players value is in a sensible range. if (!NET_ReadConnectData(packet, &data)) { NET_Log("server: error: failed to read connect data"); return; } if (!D_ValidGameMode(data.gamemission, data.gamemode) || data.max_players > NET_MAXPLAYERS) { NET_Log("server: error: invalid connect data, max_players=%d, " "gamemission=%d, gamemode=%d", data.max_players, data.gamemission, data.gamemode); return; } // Read the player's name player_name = NET_ReadString(packet); if (player_name == NULL) { NET_Log("server: error: failed to read player name"); return; } // At this point we have received a valid SYN. // Not accepting new connections? if (server_state != SERVER_WAITING_LAUNCH) { NET_Log("server: error: not in waiting launch state, server_state=%d", server_state); NET_SV_SendReject(addr, "Server is not currently accepting connections"); return; } // Before accepting a new client, check that there is a slot free. NET_SV_AssignPlayers(); num_players = NET_SV_NumPlayers(); if ((!data.drone && num_players >= NET_SV_MaxPlayers()) || NET_SV_NumClients() >= MAXNETNODES) { NET_Log("server: no more players, num_players=%d, max=%d", num_players, NET_SV_MaxPlayers()); NET_SV_SendReject(addr, "Server is full!"); return; } // TODO: Add server option to allow rejecting clients which set // lowres_turn. This is potentially desirable as the presence of such // clients affects turning resolution. // Adopt the game mode and mission of the first connecting client: if (num_players == 0 && !data.drone) { sv_gamemode = data.gamemode; sv_gamemission = data.gamemission; NET_Log("server: new game, mode=%d, mission=%d", sv_gamemode, sv_gamemission); } // Check the connecting client is playing the same game as all // the other clients if (data.gamemode != sv_gamemode || data.gamemission != sv_gamemission) { char msg[128]; NET_Log("server: wrong mode/mission, %d != %d || %d != %d", data.gamemode, sv_gamemode, data.gamemission, sv_gamemission); M_snprintf(msg, sizeof(msg), "Game mismatch: server is %s (%s), client is %s (%s)", D_GameMissionString(sv_gamemission), D_GameModeString(sv_gamemode), D_GameMissionString(data.gamemission), D_GameModeString(data.gamemode)); NET_SV_SendReject(addr, msg); return; } // Allocate a client slot if there isn't one already if (client == NULL) { // find a slot, or return if none found for (i=0; i<MAXNETNODES; ++i) { if (!clients[i].active) { client = &clients[i]; break; } } if (client == NULL) { return; } } else { // If this is a recently-disconnected client, deactivate // to allow immediate reconnection if (client->connection.state == NET_CONN_STATE_DISCONNECTED) { client->active = false; } } // Client already connected? if (client->active) { NET_Log("server: client is already initialized (duplicate SYN?)"); return; } // Activate, initialize connection NET_SV_InitNewClient(client, addr, protocol); // Save the SHA1 checksums and other details. memcpy(client->wad_sha1sum, data.wad_sha1sum, sizeof(sha1_digest_t)); memcpy(client->deh_sha1sum, data.deh_sha1sum, sizeof(sha1_digest_t)); client->is_freedoom = data.is_freedoom; client->max_players = data.max_players; client->name = M_StringDuplicate(player_name); client->recording_lowres = data.lowres_turn; client->drone = data.drone; client->player_class = data.player_class; // Send a reply back to the client, indicating a successful connection // and specifying the protocol that will be used for communications. reply = NET_Conn_NewReliable(&client->connection, NET_PACKET_TYPE_SYN); NET_WriteString(reply, PACKAGE_STRING); NET_WriteProtocol(reply, protocol); }