Пример #1
0
//runtime selection of optimized tmappers.  12/07/99  Matthew Mueller
//the reason I did it this way rather than having a *tmap_funcs that then points to a c_tmap or fp_tmap struct thats already filled in, is to avoid a second pointer dereference.
void select_tmap(char *type)
{
    if (!type)
    {
#if !defined(NO_ASM) && !defined(OGL)
        select_tmap("i386");
#elif defined(macintosh) && !defined(OGL)
        select_tmap("ppc");
#else
        select_tmap("c");
#endif
        return;
    }
#if !defined(NO_ASM) && !defined(OGL)
    if (d_stricmp(type, "i386")==0)
    {
        cur_tmap_scanline_per=asm_tmap_scanline_per;
        cur_tmap_scanline_per_nolight=asm_tmap_scanline_per;
        cur_tmap_scanline_lin=asm_tmap_scanline_lin_lighted;
        cur_tmap_scanline_lin_nolight=asm_tmap_scanline_lin;
        cur_tmap_scanline_flat=asm_tmap_scanline_flat;
        cur_tmap_scanline_shaded=asm_tmap_scanline_shaded;
    }
    else
#elif defined(macintosh) && !defined(OGL)
    if (d_stricmp(type,"ppc")==0) {
        cur_tmap_scanline_per=asm_tmap_scanline_per;
        cur_tmap_scanline_per_nolight=asm_tmap_scanline_per;
        cur_tmap_scanline_lin=c_tmap_scanline_lin;
        cur_tmap_scanline_lin_nolight=c_tmap_scanline_lin_nolight;
        cur_tmap_scanline_flat=c_tmap_scanline_flat;
        cur_tmap_scanline_shaded=c_tmap_scanline_shaded;
    }
    else
#endif
        if (d_stricmp(type,"fp")==0) {
            cur_tmap_scanline_per=c_fp_tmap_scanline_per;
            cur_tmap_scanline_per_nolight=c_fp_tmap_scanline_per_nolight;
            cur_tmap_scanline_lin=c_tmap_scanline_lin;
            cur_tmap_scanline_lin_nolight=c_tmap_scanline_lin_nolight;
            cur_tmap_scanline_flat=c_tmap_scanline_flat;
            cur_tmap_scanline_shaded=c_tmap_scanline_shaded;
        }
        else if (d_stricmp(type,"quad")==0) {
            cur_tmap_scanline_per=c_tmap_scanline_quad;
            cur_tmap_scanline_per_nolight=c_tmap_scanline_per_nolight;
            cur_tmap_scanline_lin=c_tmap_scanline_lin;
            cur_tmap_scanline_lin_nolight=c_tmap_scanline_lin_nolight;
            cur_tmap_scanline_flat=c_tmap_scanline_flat;
            cur_tmap_scanline_shaded=c_tmap_scanline_shaded;
        }
        else {
            cur_tmap_scanline_per=c_tmap_scanline_per;
            cur_tmap_scanline_per_nolight=c_tmap_scanline_per_nolight;
            cur_tmap_scanline_lin=c_tmap_scanline_lin;
            cur_tmap_scanline_lin_nolight=c_tmap_scanline_lin_nolight;
            cur_tmap_scanline_flat=c_tmap_scanline_flat;
            cur_tmap_scanline_shaded=c_tmap_scanline_shaded;
        }
}
Пример #2
0
void ogl_get_verinfo(void)
{
#ifndef OGLES
	gl_vendor = (const char *) glGetString (GL_VENDOR);
	gl_renderer = (const char *) glGetString (GL_RENDERER);
	gl_version = (const char *) glGetString (GL_VERSION);
	gl_extensions = (const char *) glGetString (GL_EXTENSIONS);

	con_printf(CON_VERBOSE, "OpenGL: vendor: %s\nOpenGL: renderer: %s\nOpenGL: version: %s\n",gl_vendor,gl_renderer,gl_version);

#ifdef _WIN32
	dglMultiTexCoord2fARB = (glMultiTexCoord2fARB_fp)wglGetProcAddress("glMultiTexCoord2fARB");
	dglActiveTextureARB = (glActiveTextureARB_fp)wglGetProcAddress("glActiveTextureARB");
	dglMultiTexCoord2fSGIS = (glMultiTexCoord2fSGIS_fp)wglGetProcAddress("glMultiTexCoord2fSGIS");
	dglSelectTextureSGIS = (glSelectTextureSGIS_fp)wglGetProcAddress("glSelectTextureSGIS");
#endif

	//add driver specific hacks here.  whee.
	if ((d_stricmp(gl_renderer,"Mesa NVIDIA RIVA 1.0\n")==0 || d_stricmp(gl_renderer,"Mesa NVIDIA RIVA 1.2\n")==0) && d_stricmp(gl_version,"1.2 Mesa 3.0")==0)
	{
		GameArg.DbgGlIntensity4Ok=0;//ignores alpha, always black background instead of transparent.
		GameArg.DbgGlReadPixelsOk=0;//either just returns all black, or kills the X server entirely
		GameArg.DbgGlGetTexLevelParamOk=0;//returns random data..
	}
	if (d_stricmp(gl_vendor,"Matrox Graphics Inc.")==0)
	{
		//displays garbage. reported by
		//  [email protected] (render="Matrox G400" version="1.1.3 5.52.015")
		//  orulz (Matrox G200)
		GameArg.DbgGlIntensity4Ok=0;
	}
#ifdef macintosh
	if (d_stricmp(gl_renderer,"3dfx Voodoo 3")==0) // strangely, includes Voodoo 2
		GameArg.DbgGlGetTexLevelParamOk=0; // Always returns 0
#endif

#ifndef NDEBUG
	con_printf(CON_VERBOSE,"gl_intensity4:%i gl_luminance4_alpha4:%i gl_rgba2:%i gl_readpixels:%i gl_gettexlevelparam:%i\n",GameArg.DbgGlIntensity4Ok,GameArg.DbgGlLuminance4Alpha4Ok,GameArg.DbgGlRGBA2Ok,GameArg.DbgGlReadPixelsOk,GameArg.DbgGlGetTexLevelParamOk);
#endif
	if (!d_stricmp(gl_extensions,"GL_EXT_texture_filter_anisotropic")==0)
	{
		glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &ogl_maxanisotropy);
		con_printf(CON_VERBOSE,"ogl_maxanisotropy:%f\n",ogl_maxanisotropy);
	}
	else if (GameCfg.TexFilt >= 3)
		GameCfg.TexFilt = 2;
#endif
}
Пример #3
0
//-----------------------------------------------------------------------------
//	Load Descent briefing text.
static int load_screen_text(const d_fname &filename, std::unique_ptr<char[]> &buf)
{
	int len, have_binary = 0;
	auto e = end(filename);
	auto ext = std::find(begin(filename), e, '.');
	if (ext == e)
		return (0);
	if (!d_stricmp(&*ext, ".txb"))
		have_binary = 1;
	
	auto tfile = PHYSFSX_openReadBuffered(filename);
	if (!tfile)
		return (0);

	len = PHYSFS_fileLength(tfile);
	buf = make_unique<char[]>(len + 1);
#if defined(DXX_BUILD_DESCENT_I)
	PHYSFS_read(tfile, buf.get(), 1, len);
#elif defined(DXX_BUILD_DESCENT_II)
	for (int x=0, i=0; i < len; i++, x++) {
		PHYSFS_read(tfile, &buf[x], 1, 1);
		if (buf[x] == 13)
			x--;
	}
#endif

	if (have_binary)
		decode_text(buf.get(), len);

	buf[len] = '\0';

	return (1);
}
Пример #4
0
static int FindArg(const char *const s)
{
	int i;

	for (i=0; i<Num_args; i++ )
		if (! d_stricmp( Args[i], s))
			return i;

	return 0;
}
Пример #5
0
//loads the named mission if exists.
//Returns true if mission loaded ok, else false.
int load_mission_by_name(char *mission_name)
{
	int i;
	mle *mission_list = build_mission_list(1);
	bool found = 0;

	for (i = 0; i < num_missions; i++)
		if (!d_stricmp(mission_name, mission_list[i].filename))
			found = load_mission(mission_list + i);

	free_mission_list(mission_list);
	return found;
}
Пример #6
0
// checks which archives are supported by PhysFS. Return 0 if some essential (HOG) is not supported
int PHYSFSX_checkSupportedArchiveTypes()
{
	const PHYSFS_ArchiveInfo **i;
	int hog_sup = 0, mvl_sup = 0;

	con_printf(CON_DEBUG, "PHYSFS: Checking supported archive types.\n");
	for (i = PHYSFS_supportedArchiveTypes(); *i != NULL; i++)
	{
		con_printf(CON_DEBUG, "PHYSFS: Supported archive: [%s], which is [%s].\n", (*i)->extension, (*i)->description);
		if (!d_stricmp((*i)->extension, "HOG"))
			hog_sup = 1;
		if (!d_stricmp((*i)->extension, "MVL"))
			mvl_sup = 1;
	}

	if (!hog_sup)
		con_printf(CON_CRITICAL, "PHYSFS: HOG not supported. The game will not work without!\n");
	if (!mvl_sup)
		con_printf(CON_URGENT, "PHYSFS: MVL not supported. Won't be able to play movies!\n");

	return hog_sup;
}
Пример #7
0
int select_mission(int anarchy_mode, char *message, int (*when_selected)(void))
{
    mle *mission_list = build_mission_list(anarchy_mode);
	int new_mission_num;

    if (num_missions <= 1)
	{
        new_mission_num = load_mission(mission_list) ? 0 : -1;
		free_mission_list(mission_list);
		(*when_selected)();
		
		return (new_mission_num >= 0);
    }
	else
	{
		mission_menu *mm;
        int i, default_mission;
        char **m;
		
		MALLOC(m, char *, num_missions);
		if (!m)
		{
			free_mission_list(mission_list);
			return 0;
		}
		
		MALLOC(mm, mission_menu, 1);
		if (!mm)
		{
			d_free(m);
			free_mission_list(mission_list);
			return 0;
		}

		mm->mission_list = mission_list;
		mm->when_selected = when_selected;
		
        default_mission = 0;
        for (i = 0; i < num_missions; i++) {
            m[i] = mission_list[i].mission_name;
            if ( !d_stricmp( m[i], GameCfg.LastMission ) )
                default_mission = i;
        }

        newmenu_listbox1( message, num_missions, m, 1, default_mission, (int (*)(listbox *, d_event *, void *))mission_menu_handler, mm );
    }

    return 1;	// presume success
}
Пример #8
0
// Play tracks from Jukebox directory. Play track specified in GameCfg.CMLevelMusicTrack[0] and loop depending on GameCfg.CMLevelMusicPlayOrder
int jukebox_play()
{
	const char *music_filename;
	uint_fast32_t size_full_filename = 0;

	if (!JukeboxSongs.list)
		return 0;

	if (CGameCfg.CMLevelMusicTrack[0] < 0 ||
		CGameCfg.CMLevelMusicTrack[0] + 1 > CGameCfg.CMLevelMusicTrack[1])
		return 0;

	music_filename = JukeboxSongs.list[CGameCfg.CMLevelMusicTrack[0]];
	if (!music_filename)
		return 0;

	size_t size_music_filename = strlen(music_filename);
	auto &cfgpath = CGameCfg.CMLevelMusicPath;
	size_t musiclen = strlen(cfgpath.data());
	size_full_filename = musiclen + size_music_filename + 1;
	RAIIdmem<char[]> full_filename;
	CALLOC(full_filename, char[], size_full_filename);
	const char *LevelMusicPath;
	if (musiclen > 4 && !d_stricmp(&cfgpath[musiclen - 4], ".m3u"))	// if it's from an M3U playlist
		LevelMusicPath = "";
	else											// if it's from a specified path
		LevelMusicPath = cfgpath.data();
	snprintf(full_filename.get(), size_full_filename, "%s%s", LevelMusicPath, music_filename);

	int played = songs_play_file(full_filename.get(), (GameCfg.CMLevelMusicPlayOrder == MUSIC_CM_PLAYORDER_LEVEL ? 1 : 0), (GameCfg.CMLevelMusicPlayOrder == MUSIC_CM_PLAYORDER_LEVEL ? nullptr : jukebox_hook_next));
	full_filename.reset();
	if (!played)
	{
		return 0;	// whoops, got an error
	}

	// Formatting a pretty message
	const char *prefix = "...";
	if (size_music_filename >= MUSIC_HUDMSG_MAXLEN) {
		music_filename += size_music_filename - MUSIC_HUDMSG_MAXLEN;
	} else {
		prefix += 3;
	}

	HUD_init_message(HM_DEFAULT, "%s %s%s", JUKEBOX_HUDMSG_PLAYING, prefix, music_filename);

	return 1;
}
Пример #9
0
int hashtable_search( hashtable *ht, char *key )	{
	int i,j,k;

	d_strlwr( key );

	k = hashtable_getkey( key );
	i = 0;
	
	while(i < ht->size )	{
		j = (k+(i++)) & ht->and_mask;
		if ( ht->key[j] == NULL )
			return -1;
		if (!d_stricmp(ht->key[j], key ))
			return ht->value[j];
	}
	return -1;
}
Пример #10
0
/* move <mission_name> to <place> on mission list, increment <place> */
void promote (mle *mission_list, char * mission_name, int * top_place)
{
	int i;
	char name[FILENAME_LEN], * t;
	strcpy(name, mission_name);
	if ((t = strchr(name,'.')) != NULL)
		*t = 0; //kill extension
	for (i = *top_place; i < num_missions; i++)
		if (!d_stricmp(mission_list[i].filename, name)) {
			//swap mission positions
			mle temp;

			temp = mission_list[*top_place];
			mission_list[*top_place] = mission_list[i];
			mission_list[i] = temp;
			++(*top_place);
			break;
		}
}
Пример #11
0
void hashtable_insert( hashtable *ht, char *key, int value )	{
	int i,j,k;

	d_strlwr( key );
	k = hashtable_getkey( key );
	i = 0;

	while(i < ht->size)	{
		j = (k+(i++)) & ht->and_mask;
		if ( ht->key[j] == NULL )	{
			ht->nitems++;
			ht->key[j] = key;
			ht->value[j] = value;
			return;
		} else if (!d_stricmp( key, ht->key[j] ))	{
			return;
		}
	}
	Error( "Out of hash slots\n" );
}
Пример #12
0
static PHYSFSX_counted_list file_getfilelist(const char *filespec, const char *dir)
{
	PHYSFSX_counted_list list{PHYSFS_enumerateFiles(dir)};
	if (!list)
		return nullptr;

	if (*filespec == '*')
		filespec++;

	const auto predicate = [&](char *i) -> bool {
		auto ext = strrchr(i, '.');
		if (ext && (!d_stricmp(ext, filespec)))
			return false;
		free(i);
		return true;
	};
	auto j = std::remove_if(list.begin(), list.end(), predicate);
	*j = NULL;
	auto NumFiles = j.get() - list.get();
	list.set_count(NumFiles);
	qsort(list.get(), NumFiles, sizeof(char *), string_array_sort_func);
	return list;
}
Пример #13
0
//loads the specfied mission from the mission list.
//build_mission_list() must have been called.
//Returns true if mission loaded ok, else false.
int load_mission(mle *mission)
{
	PHYSFS_file *mfile;
	char buf[PATH_MAX], *v;

	if (Current_mission)
		free_mission();
	Current_mission = d_malloc(sizeof(Mission));
	if (!Current_mission) return 0;
	*(mle *) Current_mission = *mission;
	Current_mission->path = d_strdup(mission->path);
	Current_mission->filename = Current_mission->path + (mission->filename - mission->path);
	Current_mission->n_secret_levels = 0;
	Current_mission->enhanced = 0;

	//init vars
	Last_level = 0;
	Last_secret_level = 0;
	memset(&Briefing_text_filename, '\0', sizeof(Briefing_text_filename));
	memset(&Ending_text_filename, '\0', sizeof(Ending_text_filename));

	// for Descent 1 missions, load descent.hog
	if (EMULATING_D1) {
		if (!PHYSFSX_contfile_init("descent.hog", 1))
			Warning("descent.hog not available, this mission may be missing some files required for briefings and exit sequence\n");
		if (!d_stricmp(Current_mission_filename, D1_MISSION_FILENAME))
			return load_mission_d1();
	}

	if (PLAYING_BUILTIN_MISSION) {
		switch (Current_mission->builtin_hogsize) {
		case SHAREWARE_MISSION_HOGSIZE:
		case MAC_SHARE_MISSION_HOGSIZE:
			strcpy(Briefing_text_filename,BIMD2_BRIEFING_FILE_SHARE);
			strcpy(Ending_text_filename,BIMD2_ENDING_FILE_SHARE);
			return load_mission_shareware();
			break;
		case OEM_MISSION_HOGSIZE:
			strcpy(Briefing_text_filename,BIMD2_BRIEFING_FILE_OEM);
			strcpy(Ending_text_filename,BIMD2_ENDING_FILE_OEM);
			return load_mission_oem();
			break;
		default:
			Int3(); // fall through
		case FULL_MISSION_HOGSIZE:
		case FULL_10_MISSION_HOGSIZE:
		case MAC_FULL_MISSION_HOGSIZE:
			strcpy(Briefing_text_filename,BIMD2_BRIEFING_FILE);
			// continue on... (use d2.mn2 from hogfile)
			break;
		}
	}

	//read mission from file

	switch (mission->location) {
	case ML_MISSIONDIR:
		strcpy(buf,MISSION_DIR);
		break;
	default:
		Int3();							//fall through
	case ML_CURDIR:
		strcpy(buf,"");
		break;
	}
	strcat(buf, mission->path);
	if (mission->descent_version == 2)
		strcat(buf,".mn2");
	else
		strcat(buf,".msn");

	PHYSFSEXT_locateCorrectCase(buf);

	mfile = PHYSFSX_openReadBuffered(buf);
	if (mfile == NULL) {
		free_mission();
		return 0;		//error!
	}

	//for non-builtin missions, load HOG
	if (!PLAYING_BUILTIN_MISSION)
	{
		strcpy(buf+strlen(buf)-4,".hog");		//change extension
		PHYSFSEXT_locateCorrectCase(buf);
		if (PHYSFSX_exists(buf,1))
			PHYSFSX_contfile_init(buf, 0);

		snprintf(Briefing_text_filename, sizeof(Briefing_text_filename), "%s.tex",Current_mission_filename);
		if (!PHYSFSX_exists(Briefing_text_filename,1))
			snprintf(Briefing_text_filename, sizeof(Briefing_text_filename), "%s.txb",Current_mission_filename);
		snprintf(Ending_text_filename, sizeof(Ending_text_filename), "%s.tex",Current_mission_filename);
		if (!PHYSFSX_exists(Ending_text_filename,1))
			snprintf(Ending_text_filename, sizeof(Ending_text_filename), "%s.txb",Current_mission_filename);
	}

	while (PHYSFSX_fgets(buf,80,mfile)) {
		if (istok(buf,"name") && !Current_mission->enhanced) {
			Current_mission->enhanced = 0;
			continue;						//already have name, go to next line
		}
		if (istok(buf,"xname") && !Current_mission->enhanced) {
			Current_mission->enhanced = 1;
			continue;						//already have name, go to next line
		}
		if (istok(buf,"zname") && !Current_mission->enhanced) {
			Current_mission->enhanced = 2;
			continue;						//already have name, go to next line
		}
		else if (istok(buf,"type"))
			continue;						//already have name, go to next line
		else if (istok(buf,"briefing")) {
			if ((v = get_value(buf)) != NULL) {
				add_term(v);
				if (strlen(v) < FILENAME_LEN && strlen(v) > 0)
				{
					char *tmp, *ptr;
					MALLOC(tmp, char, FILENAME_LEN);
					snprintf(tmp, FILENAME_LEN, "%s", v);
					if ((ptr = strrchr(tmp, '.'))) // if there's a filename extension, kill it. No one knows it's the right one.
						*ptr = '\0';
					strncat(tmp, ".tex", sizeof(char)*FILENAME_LEN); // apply tex-extenstion
					if (PHYSFSX_exists(tmp,1)) // check if this file exists ...
						snprintf(Briefing_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ...
					else // ... otherwise ...
					{
						if ((ptr = strrchr(tmp, '.')))
							*ptr = '\0';
						strncat(tmp, ".txb", sizeof(char)*FILENAME_LEN); // apply txb extension
						if (PHYSFSX_exists(tmp,1)) // check if this file exists ...
							snprintf(Briefing_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ...
					}
					d_free(tmp);
				}
			}
		}
		else if (istok(buf,"ending")) {
			if ((v = get_value(buf)) != NULL) {
				add_term(v);
				if (strlen(v) < FILENAME_LEN && strlen(v) > 0)
				{
					char *tmp, *ptr;
					MALLOC(tmp, char, FILENAME_LEN);
					snprintf(tmp, FILENAME_LEN, "%s", v);
					if ((ptr = strrchr(tmp, '.'))) // if there's a filename extension, kill it. No one knows it's the right one.
						*ptr = '\0';
					strncat(tmp, ".tex", sizeof(char)*FILENAME_LEN); // apply tex-extenstion
					if (PHYSFSX_exists(tmp,1)) // check if this file exists ...
						snprintf(Briefing_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ...
					else // ... otherwise ...
					{
						if ((ptr = strrchr(tmp, '.')))
							*ptr = '\0';
						strncat(tmp, ".txb", sizeof(char)*FILENAME_LEN); // apply txb extension
						if (PHYSFSX_exists(tmp,1)) // check if this file exists ...
							snprintf(Ending_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ...
					}
					d_free(tmp);
				}
			}
		}
		else if (istok(buf,"num_levels")) {

			if ((v=get_value(buf))!=NULL) {
				int n_levels,i;

				n_levels = atoi(v);

				for (i=0;i<n_levels;i++) {
					PHYSFSX_fgets(buf,80,mfile);
					add_term(buf);
					if (strlen(buf) <= 12) {
						strcpy(Level_names[i],buf);
						Last_level++;
					}
					else
						break;
				}

			}
		}
		else if (istok(buf,"num_secrets")) {
			if ((v=get_value(buf))!=NULL) {
				int i;

				N_secret_levels = atoi(v);

				Assert(N_secret_levels <= MAX_SECRET_LEVELS_PER_MISSION);

				for (i=0;i<N_secret_levels;i++) {
					char *t;

					PHYSFSX_fgets(buf,80,mfile);
					if ((t=strchr(buf,','))!=NULL) *t++=0;
					else
						break;

					add_term(buf);
					if (strlen(buf) <= 12) {
						strcpy(Secret_level_names[i],buf);
						Secret_level_table[i] = atoi(t);
						if (Secret_level_table[i]<1 || Secret_level_table[i]>Last_level)
							break;
						Last_secret_level--;
					}
					else
						break;
				}

			}
		}

	}

	PHYSFS_close(mfile);

	if (Last_level <= 0) {
		free_mission();		//no valid mission loaded
		return 0;
	}

	// re-read default HAM file, in case this mission brings it's own version of it
	free_polygon_models();
	read_hamfile();

	if (Current_mission->enhanced) {
		char t[50];
		extern void bm_read_extra_robots();
		sprintf(t,"%s.ham",Current_mission_filename);
		bm_read_extra_robots(t, Current_mission->enhanced);
		init_extra_robot_movie(Current_mission_filename);
	}

	return 1;
}
Пример #14
0
int ml_sort_func(mle *e0,mle *e1)
{
	return d_stricmp(e0->mission_name,e1->mission_name);

}
Пример #15
0
void verify_object( object * obj )	{

	obj->lifeleft = IMMORTAL_TIME;		//all loaded object are immortal, for now

	if ( obj->type == OBJ_ROBOT )	{
		Gamesave_num_org_robots++;

		// Make sure valid id...
		if ( obj->id >= N_robot_types )
			obj->id = obj->id % N_robot_types;

		// Make sure model number & size are correct...
		if ( obj->render_type == RT_POLYOBJ ) {
			obj->rtype.pobj_info.model_num = Robot_info[obj->id].model_num;
			obj->size = Polygon_models[obj->rtype.pobj_info.model_num].rad;

			//@@if (obj->control_type==CT_AI && Robot_info[obj->id].attack_type)
			//@@	obj->size = obj->size*3/4;
		}

		if (obj->movement_type == MT_PHYSICS) {
			obj->mtype.phys_info.mass = Robot_info[obj->id].mass;
			obj->mtype.phys_info.drag = Robot_info[obj->id].drag;
		}
	}
	else {		//Robots taken care of above

		if ( obj->render_type == RT_POLYOBJ ) {
			int i;
			char *name = Save_pof_names[obj->rtype.pobj_info.model_num];

			for (i=0;i<N_polygon_models;i++)
				if (!d_stricmp(Pof_names[i],name)) {		//found it!	
					obj->rtype.pobj_info.model_num = i;
					break;
				}
		}
	}

	if ( obj->type == OBJ_POWERUP ) {
		if ( obj->id >= N_powerup_types )	{
			obj->id = 0;
			Assert( obj->render_type != RT_POLYOBJ );
		}
		obj->control_type = CT_POWERUP;

		obj->size = Powerup_info[obj->id].size;

		if (Game_mode & GM_NETWORK)
		{
			if (multi_powerup_is_4pack(obj->id))
			{
				PowerupsInMine[obj->id-1]+=4;
				MaxPowerupsAllowed[obj->id-1]+=4;
			}
			else
			{
				PowerupsInMine[obj->id]++;
				MaxPowerupsAllowed[obj->id]++;
			}
		}
	}

	if ( obj->type == OBJ_WEAPON )	{
		if ( obj->id >= N_weapon_types )	{
			obj->id = 0;
			Assert( obj->render_type != RT_POLYOBJ );
		}
	}

	if ( obj->type == OBJ_CNTRLCEN ) {
		int i;

		obj->render_type = RT_POLYOBJ;
		obj->control_type = CT_CNTRLCEN;

		// Make model number is correct...	
		for (i=0; i<Num_total_object_types; i++ )	
			if ( ObjType[i] == OL_CONTROL_CENTER )		{
				obj->rtype.pobj_info.model_num = ObjId[i];
				obj->shields = ObjStrength[i];
				break;		
			}
	}

	if ( obj->type == OBJ_PLAYER )	{
		//int i;

		//Assert(obj == Player);

		if ( obj == ConsoleObject )		
			init_player_object();
		else
			if (obj->render_type == RT_POLYOBJ)	//recover from Matt's pof file matchup bug
				obj->rtype.pobj_info.model_num = Player_ship->model_num;

		//Make sure orient matrix is orthogonal
		check_and_fix_matrix(&obj->orient);

		obj->id = Gamesave_num_players++;
	}

	if (obj->type == OBJ_HOSTAGE) {

		if (obj->id > N_hostage_types)
			obj->id = 0;

		obj->render_type = RT_HOSTAGE;
		obj->control_type = CT_POWERUP;
	}

}
Пример #16
0
//loads the specfied mission from the mission list.
//build_mission_list() must have been called.
//Returns true if mission loaded ok, else false.
int load_mission(mle *mission)
{
	PHYSFS_file *mfile;
	char buf[PATH_MAX], *v;

	if (Current_mission)
		free_mission();
	Current_mission = d_malloc(sizeof(Mission));
	if (!Current_mission) return 0;
	*(mle *) Current_mission = *mission;
	Current_mission->path = d_strdup(mission->path);
	Current_mission->filename = Current_mission->path + (mission->filename - mission->path);
	Current_mission->n_secret_levels = 0;

	//init vars
	Last_level = 0;
	Last_secret_level = 0;
	memset(&Briefing_text_filename, '\0', sizeof(Briefing_text_filename));
	memset(&Ending_text_filename, '\0', sizeof(Ending_text_filename));
	Secret_level_table = NULL;
	Level_names = NULL;
	Secret_level_names = NULL;

	// for Descent 1 missions, load descent.hog
	if (!PHYSFSX_contfile_init("descent.hog", 1))
		Error("descent.hog not available!\n");
	if (!d_stricmp(Current_mission_filename, D1_MISSION_FILENAME))
		return load_mission_d1();

	//read mission from file

	switch (mission->location) {
	case ML_MISSIONDIR:
		strcpy(buf,MISSION_DIR);
		break;
	default:
		Int3();							//fall through
	case ML_CURDIR:
		strcpy(buf,"");
		break;
	}
	strcat(buf, mission->path);
	strcat(buf,".msn");

	PHYSFSEXT_locateCorrectCase(buf);

	mfile = PHYSFSX_openReadBuffered(buf);
	if (mfile == NULL) {
		free_mission();
		return 0;		//error!
	}

	//for non-builtin missions, load HOG
	strcpy(buf+strlen(buf)-4,".hog");		//change extension
	PHYSFSEXT_locateCorrectCase(buf);
	if (PHYSFSX_exists(buf,1))
		PHYSFSX_contfile_init(buf, 0);

	snprintf(Briefing_text_filename, sizeof(Briefing_text_filename), "%s.tex",Current_mission_filename);
	if (!PHYSFSX_exists(Briefing_text_filename,1))
		snprintf(Briefing_text_filename, sizeof(Briefing_text_filename), "%s.txb",Current_mission_filename);
	snprintf(Ending_text_filename, sizeof(Ending_text_filename), "%s.tex",Current_mission_filename);
	if (!PHYSFSX_exists(Ending_text_filename,1))
		snprintf(Ending_text_filename, sizeof(Ending_text_filename), "%s.txb",Current_mission_filename);

	while (PHYSFSX_fgets(buf,sizeof(buf),mfile)) {
		if (istok(buf,"type"))
			continue;						//already have name, go to next line
		else if (istok(buf,"briefing")) {
			if ((v = get_value(buf)) != NULL) {
				add_term(v);
				if (strlen(v) < FILENAME_LEN && strlen(v) > 0)
				{
					char *tmp, *ptr;
					MALLOC(tmp, char, FILENAME_LEN);
					snprintf(tmp, FILENAME_LEN, "%s", v);
					if ((ptr = strrchr(tmp, '.'))) // if there's a filename extension, kill it. No one knows it's the right one.
						*ptr = '\0';
					strncat(tmp, ".tex", sizeof(char)*FILENAME_LEN); // apply tex-extenstion
					if (PHYSFSX_exists(tmp,1)) // check if this file exists ...
						snprintf(Briefing_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ...
					else // ... otherwise ...
					{
						if ((ptr = strrchr(tmp, '.')))
							*ptr = '\0';
						strncat(tmp, ".txb", sizeof(char)*FILENAME_LEN); // apply txb extension
						if (PHYSFSX_exists(tmp,1)) // check if this file exists ...
							snprintf(Briefing_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ...
					}
					d_free(tmp);
				}
			}
		}
		else if (istok(buf,"ending")) {
			if ((v = get_value(buf)) != NULL) {
				add_term(v);
				if (strlen(v) < FILENAME_LEN && strlen(v) > 0)
				{
					char *tmp, *ptr;
					MALLOC(tmp, char, FILENAME_LEN);
					snprintf(tmp, FILENAME_LEN, "%s", v);
					if ((ptr = strrchr(tmp, '.'))) // if there's a filename extension, kill it. No one knows it's the right one.
						*ptr = '\0';
					strncat(tmp, ".tex", sizeof(char)*FILENAME_LEN); // apply tex-extenstion
					if (PHYSFSX_exists(tmp,1)) // check if this file exists ...
						snprintf(Briefing_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ...
					else // ... otherwise ...
					{
						if ((ptr = strrchr(tmp, '.')))
							*ptr = '\0';
						strncat(tmp, ".txb", sizeof(char)*FILENAME_LEN); // apply txb extension
						if (PHYSFSX_exists(tmp,1)) // check if this file exists ...
							snprintf(Ending_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ...
					}
					d_free(tmp);
				}
			}
		}
		else if (istok(buf,"num_levels")) {

			if ((v=get_value(buf))!=NULL) {
				int n_levels,i;

				n_levels = atoi(v);
				
				Assert(n_levels <= MAX_LEVELS_PER_MISSION);
				n_levels = min(n_levels, MAX_LEVELS_PER_MISSION);
				
				MALLOC(Level_names, d_fname, n_levels);
				if (!Level_names)
				{
					free_mission();
					return 0;
				}

				for (i=0;i<n_levels;i++) {
					PHYSFSX_fgets(buf,sizeof(buf),mfile);
					add_term(buf);
					if (strlen(buf) <= 12) {
						strcpy(Level_names[i],buf);
						Last_level++;
					}
					else
						break;
				}

			}
		}
		else if (istok(buf,"num_secrets")) {
			if ((v=get_value(buf))!=NULL) {
				int i;

				N_secret_levels = atoi(v);

				Assert(N_secret_levels <= MAX_SECRET_LEVELS_PER_MISSION);
				N_secret_levels = min(N_secret_levels, MAX_SECRET_LEVELS_PER_MISSION);

				MALLOC(Secret_level_names, d_fname, N_secret_levels);
				if (!Secret_level_names)
				{
					free_mission();
					return 0;
				}
				
				MALLOC(Secret_level_table, ubyte, N_secret_levels);
				if (!Secret_level_table)
				{
					free_mission();
					return 0;
				}
				
				for (i=0;i<N_secret_levels;i++) {
					char *t;

					PHYSFSX_fgets(buf,sizeof(buf),mfile);
					if ((t=strchr(buf,','))!=NULL) *t++=0;
					else
						break;

					add_term(buf);
					if (strlen(buf) <= 12) {
						strcpy(Secret_level_names[i],buf);
						Secret_level_table[i] = atoi(t);
						if (Secret_level_table[i]<1 || Secret_level_table[i]>Last_level)
							break;
						Last_secret_level--;
					}
					else
						break;
				}

			}
		}

	}

	PHYSFS_close(mfile);

	if (Last_level <= 0) {
		free_mission();		//no valid mission loaded
		return 0;
	}

	return 1;
}
Пример #17
0
/* Loads music file names from a given directory or M3U playlist */
void jukebox_load()
{
	jukebox_unload();

	// Check if it's an M3U file
	auto &cfgpath = CGameCfg.CMLevelMusicPath;
	size_t musiclen = strlen(cfgpath.data());
	if (musiclen > 4 && !d_stricmp(&cfgpath[musiclen - 4], ".m3u"))
		read_m3u();
	else	// a directory
	{
		class PHYSFS_path_deleter
		{
		public:
			void operator()(const char *const p) const noexcept
			{
				PHYSFS_removeFromSearchPath(p);
			}
		};
		std::unique_ptr<const char, PHYSFS_path_deleter> new_path;
		const char *sep = PHYSFS_getDirSeparator();
		size_t seplen = strlen(sep);

		// stick a separator on the end if necessary.
		if (musiclen >= seplen)
		{
			auto p = &cfgpath[musiclen - seplen];
			if (strcmp(p, sep))
				cfgpath.copy_if(musiclen, sep, seplen);
		}

		const auto p = cfgpath.data();
		// Read directory using PhysicsFS
		if (PHYSFS_isDirectory(p))	// find files in relative directory
			JukeboxSongs.list.reset(PHYSFSX_findFiles(p, jukebox_exts));
		else
		{
			if (PHYSFSX_isNewPath(p))
				new_path.reset(p);
			PHYSFS_addToSearchPath(p, 0);

			// as mountpoints are no option (yet), make sure only files originating from GameCfg.CMLevelMusicPath are aded to the list.
			JukeboxSongs.list.reset(PHYSFSX_findabsoluteFiles("", p, jukebox_exts));
		}

		if (!JukeboxSongs.list)
		{
			return;
		}
		JukeboxSongs.num_songs = std::distance(JukeboxSongs.list.begin(), JukeboxSongs.list.end());
	}

	if (JukeboxSongs.num_songs)
	{
		con_printf(CON_DEBUG,"Jukebox: %d music file(s) found in %s", JukeboxSongs.num_songs, cfgpath.data());
		if (CGameCfg.CMLevelMusicTrack[1] != JukeboxSongs.num_songs)
		{
			CGameCfg.CMLevelMusicTrack[1] = JukeboxSongs.num_songs;
			CGameCfg.CMLevelMusicTrack[0] = 0; // number of songs changed so start from beginning.
		}
	}
	else
	{
		CGameCfg.CMLevelMusicTrack[0] = -1;
		CGameCfg.CMLevelMusicTrack[1] = -1;
		con_puts(CON_DEBUG,"Jukebox music could not be found!");
	}
}
Пример #18
0
int mix_play_file(char *filename, int loop, void (*hook_finished_track)())
{
	SDL_RWops *rw = NULL;
	PHYSFS_file *filehandle = NULL;
	char full_path[PATH_MAX];
	char *fptr;
	unsigned int bufsize = 0;

	mix_free_music();	// stop and free what we're already playing, if anything

	fptr = strrchr(filename, '.');

	if (fptr == NULL)
		return 0;

	// It's a .hmp!
	if (!d_stricmp(fptr, ".hmp"))
	{
		hmp2mid(filename, &current_music_hndlbuf, &bufsize);
		rw = SDL_RWFromConstMem(current_music_hndlbuf,bufsize*sizeof(char));
		current_music = Mix_LoadMUS_RW(rw);
	}

	// try loading music via given filename
	if (!current_music)
		current_music = Mix_LoadMUS(filename);

	// allow the shell convention tilde character to mean the user's home folder
	// chiefly used for default jukebox level song music referenced in 'descent.m3u' for Mac OS X
	if (!current_music && *filename == '~')
	{
		snprintf(full_path, PATH_MAX, "%s%s", PHYSFS_getUserDir(),
				 &filename[1 + (!strncmp(&filename[1], PHYSFS_getDirSeparator(), strlen(PHYSFS_getDirSeparator())) ? 
				 strlen(PHYSFS_getDirSeparator()) : 0)]);
		current_music = Mix_LoadMUS(full_path);
		if (current_music)
			filename = full_path;	// used later for possible error reporting
	}
		

	// no luck. so it might be in Searchpath. So try to build absolute path
	if (!current_music)
	{
		PHYSFSX_getRealPath(filename, full_path);
		current_music = Mix_LoadMUS(full_path);
		if (current_music)
			filename = full_path;	// used later for possible error reporting
	}

	// still nothin'? Let's open via PhysFS in case it's located inside an archive
	if (!current_music)
	{
		filehandle = PHYSFS_openRead(filename);
		if (filehandle != NULL)
		{
			current_music_hndlbuf = d_realloc(current_music_hndlbuf, sizeof(char *)*PHYSFS_fileLength(filehandle));
			bufsize = PHYSFS_read(filehandle, current_music_hndlbuf, sizeof(char), PHYSFS_fileLength(filehandle));
			rw = SDL_RWFromConstMem(current_music_hndlbuf,bufsize*sizeof(char));
			PHYSFS_close(filehandle);
			current_music = Mix_LoadMUS_RW(rw);
		}
	}

	if (current_music)
	{
		Mix_PlayMusic(current_music, (loop ? -1 : 1));
		Mix_HookMusicFinished(hook_finished_track ? hook_finished_track : mix_free_music);
		return 1;
	}
	else
	{
		con_printf(CON_CRITICAL,"Music %s could not be loaded: %s\n", filename, Mix_GetError());
		mix_stop_music();
	}

	return 0;
}
Пример #19
0
static void ReadCmdArgs(Inilist &ini, Arglist &Args)
{
	for (Arglist::iterator pp = Args.begin(), end = Args.end(); pp != end; ++pp)
	{
		const char *p = pp->c_str();
	// System Options

		if (!d_stricmp(p, "-help") || !d_stricmp(p, "-h") || !d_stricmp(p, "-?") || !d_stricmp(p, "?"))
			CGameArg.SysShowCmdHelp = true;
		else if (!d_stricmp(p, "-nonicefps"))
			CGameArg.SysNoNiceFPS = true;
		else if (!d_stricmp(p, "-maxfps"))
			CGameArg.SysMaxFPS = arg_integer(pp, end);
		else if (!d_stricmp(p, "-hogdir"))
			CGameArg.SysHogDir = arg_string(pp, end);
#if PHYSFS_VER_MAJOR >= 2
		else if (!d_stricmp(p, "-add-missions-dir"))
			CGameArg.SysMissionDir = arg_string(pp, end);
#endif
		else if (!d_stricmp(p, "-nohogdir"))
		{
			/* No effect on non-Unix.  Ignore it so that players can
			 * pass it via a cross-platform ini.
			 */
#if defined(__unix__)
			CGameArg.SysNoHogDir = true;
#endif
		}
		else if (!d_stricmp(p, "-use_players_dir"))
			CGameArg.SysUsePlayersDir = static_cast<int8_t>(- (sizeof(PLAYER_DIRECTORY_TEXT) - 1));
		else if (!d_stricmp(p, "-lowmem"))
			CGameArg.SysLowMem = true;
		else if (!d_stricmp(p, "-pilot"))
			CGameArg.SysPilot = arg_string(pp, end);
		else if (!d_stricmp(p, "-record-demo-format"))
			CGameArg.SysRecordDemoNameTemplate = arg_string(pp, end);
		else if (!d_stricmp(p, "-auto-record-demo"))
			CGameArg.SysAutoRecordDemo = true;
		else if (!d_stricmp(p, "-window"))
			CGameArg.SysWindow = true;
		else if (!d_stricmp(p, "-noborders"))
			CGameArg.SysNoBorders = true;
		else if (!d_stricmp(p, "-notitles"))
			CGameArg.SysNoTitles = true;
#if defined(DXX_BUILD_DESCENT_II)
		else if (!d_stricmp(p, "-nomovies"))
			GameArg.SysNoMovies 		= 1;
#endif
		else if (!d_stricmp(p, "-autodemo"))
			CGameArg.SysAutoDemo = true;

	// Control Options

		else if (!d_stricmp(p, "-nocursor"))
			CGameArg.CtlNoCursor 		= true;
		else if (!d_stricmp(p, "-nomouse"))
			CGameArg.CtlNoMouse 		= true;
		else if (!d_stricmp(p, "-nojoystick"))
		{
#if DXX_MAX_JOYSTICKS
			CGameArg.CtlNoJoystick		= 1;
#endif
		}
		else if (!d_stricmp(p, "-nostickykeys"))
			CGameArg.CtlNoStickyKeys	= true;

	// Sound Options

		else if (!d_stricmp(p, "-nosound"))
			CGameArg.SndNoSound		= 1;
		else if (!d_stricmp(p, "-nomusic"))
			CGameArg.SndNoMusic = true;
#if defined(DXX_BUILD_DESCENT_II)
		else if (!d_stricmp(p, "-sound11k"))
			GameArg.SndDigiSampleRate 		= SAMPLE_RATE_11K;
#endif
		else if (!d_stricmp(p, "-nosdlmixer"))
		{
#if DXX_USE_SDLMIXER
			CGameArg.SndDisableSdlMixer = true;
#endif
		}

	// Graphics Options

		else if (!d_stricmp(p, "-lowresfont"))
			CGameArg.GfxSkipHiresFNT = true;
#if defined(DXX_BUILD_DESCENT_II)
		else if (!d_stricmp(p, "-lowresgraphics"))
			GameArg.GfxSkipHiresGFX	= 1;
		else if (!d_stricmp(p, "-lowresmovies"))
			GameArg.GfxSkipHiresMovie 		= 1;
#endif
#if DXX_USE_OGL
	// OpenGL Options

		else if (!d_stricmp(p, "-gl_fixedfont"))
			CGameArg.OglFixedFont = true;
		else if (!d_stricmp(p, "-gl_syncmethod"))
			CGameArg.OglSyncMethod = arg_enum<SyncGLMethod>(pp, end);
		else if (!d_stricmp(p, "-gl_syncwait"))
			CGameArg.OglSyncWait = arg_integer(pp, end);
		else if (!d_stricmp(p, "-gl_darkedges"))
			CGameArg.OglDarkEdges = true;
#endif

	// Multiplayer Options

#if DXX_USE_UDP
		else if (!d_stricmp(p, "-udp_hostaddr"))
			CGameArg.MplUdpHostAddr = arg_string(pp, end);
		else if (!d_stricmp(p, "-udp_hostport"))
			/* Peers use -udp_myport to change, so peer cannot set a
			 * privileged port.
			 */
			arg_port_number(pp, end, CGameArg.MplUdpHostPort, false);
		else if (!d_stricmp(p, "-udp_myport"))
		{
			arg_port_number(pp, end, CGameArg.MplUdpMyPort, false);
		}
		else if (!d_stricmp(p, "-no-tracker"))
		{
			/* Always recognized.  No-op if tracker support compiled
			 * out. */
#if DXX_USE_TRACKER
			CGameArg.MplTrackerAddr.clear();
#endif
		}
#if DXX_USE_TRACKER
		else if (!d_stricmp(p, "-tracker_hostaddr"))
		{
			CGameArg.MplTrackerAddr = arg_string(pp, end);
		}
		else if (!d_stricmp(p, "-tracker_hostport"))
			arg_port_number(pp, end, CGameArg.MplTrackerPort, true);
#endif
#endif

#if defined(DXX_BUILD_DESCENT_I)
		else if (!d_stricmp(p, "-nobm"))
			GameArg.EdiNoBm 		= 1;
#elif defined(DXX_BUILD_DESCENT_II)
#if DXX_USE_EDITOR
	// Editor Options

		else if (!d_stricmp(p, "-autoload"))
			GameArg.EdiAutoLoad = arg_string(pp, end);
		else if (!d_stricmp(p, "-macdata"))
			GameArg.EdiMacData 		= 1;
		else if (!d_stricmp(p, "-hoarddata"))
			GameArg.EdiSaveHoardData 	= 1;
#endif
#endif

	// Debug Options

		else if (!d_stricmp(p, "-debug"))
			CGameArg.DbgVerbose 	= CON_DEBUG;
		else if (!d_stricmp(p, "-verbose"))
			CGameArg.DbgVerbose 	= CON_VERBOSE;

		else if (!d_stricmp(p, "-no-grab"))
			CGameArg.DbgForbidConsoleGrab = true;
		else if (!d_stricmp(p, "-safelog"))
			CGameArg.DbgSafelog = true;
		else if (!d_stricmp(p, "-norun"))
			CGameArg.DbgNoRun = true;
		else if (!d_stricmp(p, "-renderstats"))
			CGameArg.DbgRenderStats = true;
		else if (!d_stricmp(p, "-text"))
			CGameArg.DbgAltTex = arg_string(pp, end);
		else if (!d_stricmp(p, "-tmap"))
			CGameArg.DbgTexMap = arg_string(pp, end);
		else if (!d_stricmp(p, "-showmeminfo"))
			CGameArg.DbgShowMemInfo 		= 1;
		else if (!d_stricmp(p, "-nodoublebuffer"))
			CGameArg.DbgNoDoubleBuffer = true;
		else if (!d_stricmp(p, "-bigpig"))
			CGameArg.DbgNoCompressPigBitmap = true;
		else if (!d_stricmp(p, "-16bpp"))
			CGameArg.DbgBpp		= 16;

#if DXX_USE_OGL
		else if (!d_stricmp(p, "-gl_oldtexmerge"))
			CGameArg.DbgUseOldTextureMerge = true;
		else if (!d_stricmp(p, "-gl_intensity4_ok"))
			CGameArg.DbgGlIntensity4Ok = arg_integer(pp, end);
		else if (!d_stricmp(p, "-gl_luminance4_alpha4_ok"))
			CGameArg.DbgGlLuminance4Alpha4Ok = arg_integer(pp, end);
		else if (!d_stricmp(p, "-gl_rgba2_ok"))
			CGameArg.DbgGlRGBA2Ok = arg_integer(pp, end);
		else if (!d_stricmp(p, "-gl_readpixels_ok"))
			CGameArg.DbgGlReadPixelsOk = arg_integer(pp, end);
		else if (!d_stricmp(p, "-gl_gettexlevelparam_ok"))
			CGameArg.DbgGlGetTexLevelParamOk = arg_integer(pp, end);
#else
		else if (!d_stricmp(p, "-hwsurface"))
			CGameArg.DbgSdlHWSurface = true;
		else if (!d_stricmp(p, "-asyncblit"))
			CGameArg.DbgSdlASyncBlit = true;
#endif
		else if (!d_stricmp(p, "-ini"))
		{
			ini.emplace_back(arg_string(pp, end));
			if (ini.size() > 10)
				throw nesting_depth_exceeded();
			ReadIniArgs(ini);
		}
		else
			throw unhandled_argument(std::move(*pp));
	}
}
Пример #20
0
//loads a level (.LVL) file from disk
//returns 0 if success, else error code
int load_level(const char * filename_passed)
{
#ifdef EDITOR
	int use_compiled_level=1;
#endif
	PHYSFS_file * LoadFile;
	char filename[PATH_MAX];
	int sig, minedata_offset, gamedata_offset, hostagetext_offset;
	int mine_err, game_err;
#ifdef NETWORK
	int i;
#endif

#ifdef NETWORK
   if (Game_mode & GM_NETWORK)
	 {
	  for (i=0;i<MAX_POWERUP_TYPES;i++)
		{
			MaxPowerupsAllowed[i]=0;
			PowerupsInMine[i]=0;
		}
	 }
#endif

	#ifdef COMPACT_SEGS
	ncache_flush();
	#endif

	#ifndef RELEASE
	Level_being_loaded = filename_passed;
	#endif

	strcpy(filename,filename_passed);

#ifdef EDITOR
	//if we have the editor, try the LVL first, no matter what was passed.
	//if we don't have an LVL, try what was passed or SDL/RDL  
	//if we don't have the editor, we just use what was passed

	change_filename_extension(filename,filename_passed,".lvl");
	use_compiled_level = 0;

	if (!PHYSFSX_exists(filename,1))
	{
		char *p = strrchr(filename_passed, '.');

		if (d_stricmp(p, ".lvl"))
			strcpy(filename, filename_passed);	// set to what was passed
		else
			change_filename_extension(filename, filename, ".rdl");
		use_compiled_level = 1;
	}		
#endif

	if (!PHYSFSX_exists(filename,1))
		sprintf(filename,"%s%s",MISSION_DIR,filename_passed);

	LoadFile = PHYSFSX_openReadBuffered( filename );

	if (!LoadFile)	{
		#ifdef EDITOR
			return 1;
		#else
			Error("Can't open file <%s>\n",filename);
		#endif
	}

	strcpy( Gamesave_current_filename, filename );

	sig                      = PHYSFSX_readInt(LoadFile);
	Gamesave_current_version = PHYSFSX_readInt(LoadFile);
	minedata_offset          = PHYSFSX_readInt(LoadFile);
	gamedata_offset          = PHYSFSX_readInt(LoadFile);

	Assert(sig == MAKE_SIG('P','L','V','L'));
	(void)sig;

	if (Gamesave_current_version < 5)
		hostagetext_offset = PHYSFSX_readInt(LoadFile);

	PHYSFSX_fseek(LoadFile,minedata_offset,SEEK_SET);
	#ifdef EDITOR
	if (!use_compiled_level)
		mine_err = load_mine_data(LoadFile);
	else
	#endif
		//NOTE LINK TO ABOVE!!
		mine_err = load_mine_data_compiled(LoadFile);

	/* !!!HACK!!!
	 * Descent 1 - Level 19: OBERON MINE has some ugly overlapping rooms (segment 484).
	 * HACK to make this issue less visible by moving one vertex a little.
	 */
	if (Current_mission && !d_stricmp("Descent: First Strike",Current_mission_longname) && !d_stricmp("level19.rdl",filename) && PHYSFS_fileLength(LoadFile) == 136706)
		Vertices[1905].z =-385*F1_0;

	if (mine_err == -1) {   //error!!
		PHYSFS_close(LoadFile);
		return 2;
	}

	PHYSFSX_fseek(LoadFile,gamedata_offset,SEEK_SET);
	game_err = load_game_data(LoadFile);

	if (game_err == -1) {   //error!!
		PHYSFS_close(LoadFile);
		return 3;
	}

	(void)hostagetext_offset;

	//======================== CLOSE FILE =============================

	PHYSFS_close( LoadFile );

	#if 0	//def EDITOR
	#ifndef RELEASE
	write_game_text_file(filename);
	if (Errors_in_mine) {
		if (is_real_level(filename)) {
			char  ErrorMessage[200];

			sprintf( ErrorMessage, "Warning: %i errors in %s!\n", Errors_in_mine, Level_being_loaded );
			stop_time();
			gr_palette_load(gr_palette);
			nm_messagebox( NULL, 1, "Continue", ErrorMessage );
			start_time();
		}
	}
	#endif
	#endif

	#ifdef EDITOR
	//If an old version, ask the use if he wants to save as new version
	if (((LEVEL_FILE_VERSION>1) && Gamesave_current_version<LEVEL_FILE_VERSION) || mine_err==1 || game_err==1) {
		char  ErrorMessage[200];

		sprintf( ErrorMessage, "You just loaded a old version level.  Would\n"
						"you like to save it as a current version level?");

		gr_palette_load(gr_palette);
		if (nm_messagebox( NULL, 2, "Don't Save", "Save", ErrorMessage )==1)
			save_level(filename);
	}
	#endif

	#ifdef EDITOR
	if (EditorWindow)
		editor_status_fmt("Loaded NEW mine %s, \"%s\"",filename,Current_level_name);
	#endif

	#if !defined(NDEBUG) && !defined(COMPACT_SEGS)
	if (check_segment_connections())
		nm_messagebox( "ERROR", 1, "Ok", 
				"Connectivity errors detected in\n"
				"mine.  See monochrome screen for\n"
				"details, and contact Matt or Mike." );
	#endif

	return 0;
}