Example #1
0
/*
 *	Loads control panel from file.
 *
 *	The given path must be a prefix to the control panel directory
 *	(not an actual file).  The appropriate files will be loaded
 *	in the directory specified by path.
 *
 *	Returns non-zero on error.
 */
int CPLoadFromFile(ControlPanel *cp, const char *path)
{
        FILE		*fp;
        char		*buf = NULL;

	char		*cp_file,
			*cp_tex_file;

	struct stat	stat_buf;

	int		ins_num = -1;
	CPIns		*ins = NULL;
	

	if((cp == NULL) || (path == NULL))
	    return(-1);

	if(*path == '\0')
	    return(-1);

        if(stat(path, &stat_buf))
	{
	    fprintf(
		stderr,
		"%s: No such directory.\n",
		path
	    );
	    return(-1);
	}

	/* Get file names. */
	/* Control panel configuration file. */
	cp_file = STRDUP(
	    PrefixPaths(path, SAR_DEF_INSTRUMENTS_FILE)
	);
	/* Control panel texture. */
        cp_tex_file = STRDUP(
            PrefixPaths(path, SAR_DEF_CONTROL_PANEL_TEX_FILE)
        );

#define DO_FREE_LOCALS	{	\
 free(cp_file);			\
 free(cp_tex_file);		\
}

	/* Check if required files exist. */
	if(stat(cp_file,  &stat_buf))
        {
            fprintf(stderr, "%s: No such file.\n", cp_file);
	    DO_FREE_LOCALS
            return(-1);
        }
Example #2
0
/*
 *	Creates a new joystick calibrator window.
 */
jc_struct *JCNew(gint argc, gchar **argv)
{
	gint i, status;
	const gchar *s, *s2, *arg;
	js_data_struct *jsd;
	jc_struct *jc = (jc_struct *)g_malloc0(sizeof(jc_struct));
	if(jc == NULL)
	    return(jc);


	/* Begin resetting jc structure. */
	jc->initialized = TRUE;
	jc->map_state = FALSE;
	jc->processing = FALSE;

	/* Reset joystick data structure values. */
	jsd = &jc->jsd;
	jsd->name = NULL;
	jsd->axis = NULL;
	jsd->total_axises = 0;
	jsd->button = NULL;
	jsd->total_buttons = 0;
	jsd->device_name = NULL;
	jsd->calibration_file = NULL;
	jsd->fd = -1;
	jsd->flags = 0;
	jsd->driver_version = 0;

	jc->manage_toid = (guint)-1;
	jc->calib_file = NULL;
	jc->tried_load_device_on_init = FALSE;


	/* Set default joystick calibration file path. */
	s = g_getenv(ENV_VAR_NAME_HOME);
	if(s == NULL)
	     s2 = JSDefaultCalibration;
	else
	     s2 = PrefixPaths(s, JSDefaultCalibration);
	jc->calib_file = STRDUP(s2);
	jc->tried_load_device_on_init = FALSE;

	/* Reset has changes marker. */
	jc->has_changes = FALSE;


	/* Create widgets for the joystick calibrator window. */
	status = JCCreateWidgets(jc, argc, argv);
	if(status)
	{
	    g_free(jc);
	    jc = NULL;
	    return(jc);
	}

	/* Set timeout callback. */
	jc->manage_toid = gtk_timeout_add(
	    16,                 /* Every 16 milliseconds. */
	    (GtkFunction)JCTimeoutCB,
	    (gpointer)jc
	);


	/* Handle arguments. */
	for(i = 1; i < argc; i++)
	{
	    arg = argv[i];
	    if(arg == NULL)
		continue;

	    /* Specify alternate calibration file. */
	    if(strcasepfx(arg, "-f"))
	    {
		i++;
		if(i < argc)
		{
		    g_free(jc->calib_file);
		    jc->calib_file = (argv[i] != NULL) ?
			g_strdup(argv[i]) : NULL;
		}
		else
		{
		    g_printerr(
			"%s: Requires argument.\n",
			argv[i - 1]
		    );
		}
	    }
	    /* Specify startup device. */
	    else if(strcasepfx(arg, "-d"))
	    {
		i++;
		if(i < argc)
		{
		    GtkCombo *combo = (GtkCombo *)jc->js_device_combo;

		    if(combo != NULL)
			gtk_entry_set_text(
			    GTK_ENTRY(combo->entry),
			    argv[i]
		        );
		}
		else
		{
		    g_printerr(
			"%s: Requires argument.\n",
			argv[i - 1] 
		    );
		}
	    }
	}


	return(jc);
}
Example #3
0
/*
 *      Initializes the joystick and stores the new initialized values
 *      into the jsd structure.
 *
 *      If the device is not specified (set to NULL), then it will
 *      be defauled to JSDefaultDevice.
 *
 *      If the calibration file is not specified (set to NULL), then
 *      it will be defaulted to JSDefaultCalibration. The HOME
 *      enviroment value will be used as the prefix to the path of
 *      JSDefaultCalibration. The calibration file does not have to
 *      exist.
 *
 *	Available flags are:
 *
 *	JSFlagNonBlocking		Open in non-blocking mode.
 *	JSFlagForceFeedback		Open in read/write mode.
 */
int JSInit(
	js_data_struct *jsd,
	const char *device,
	const char *calibration,
	unsigned int flags
)
{
	int i;
	js_axis_struct *axis;
	js_button_struct *button;

#if defined(__linux__) || defined(__FreeBSD__)
	unsigned char axes = 2;
	unsigned char buttons = 2;
	int version = 0x000800;

# ifndef LINUX_JS_NAME_MAX
#  define LINUX_JS_NAME_MAX	128
# endif

	char name[LINUX_JS_NAME_MAX] = "Unknown";

#endif	/* __linux__ || __FreeBSD__ */


	if(jsd == NULL)
	    return(JSBadValue);

	/* Reset values */
	jsd->name = NULL;

	jsd->axis = NULL;
	jsd->total_axises = 0;

	jsd->button = NULL;
	jsd->total_buttons = 0;

	jsd->device_name = NULL;
	jsd->calibration_file = NULL;

	jsd->events_received = 0;
	jsd->events_sent = 0;

	jsd->fd = -1;
	jsd->flags = 0;
	jsd->driver_version = 0;
	jsd->last_calibrated = 0;
	jsd->force_feedback = NULL;


	/* Set default device name as needed */
	if(device == NULL)
	    device = JSDefaultDevice;

	/* Set default calibration file name as needed */
	if(calibration == NULL)
	{
	    const char *home = getenv("HOME");
	    calibration = PrefixPaths(
		(home != NULL) ? home : "/",
		JSDefaultCalibration
	    );
	    if(calibration == NULL)
		calibration = JSDefaultCalibration;
	}

	/* From this point on device and calibration are not NULL, so
	 * record device and calibration file names on the jsd
	 */
	jsd->device_name = STRDUP(device);
	jsd->calibration_file = STRDUP(calibration);


#if defined(__linux__) || defined(__FreeBSD__)
	/* Open joystick */
	jsd->fd = open(jsd->device_name, O_RDONLY);
	if(jsd->fd < 0)
	{
	    JSClose(jsd);
	    return(JSNoAccess);
	}
#endif

#if defined(__linux__)
	/* Fetch device values */
	/* Raw version string */
	ioctl(jsd->fd, JSIOCGVERSION, &version);
	jsd->driver_version = (unsigned int)version;

	/* Total number of axises */
	ioctl(jsd->fd, JSIOCGAXES, &axes);	/* Total axises */
	jsd->total_axises = axes;

	/* Total number of buttons */
	ioctl(jsd->fd, JSIOCGBUTTONS, &buttons);	/* Total buttons */
	jsd->total_buttons = buttons;

	/* Device descriptive name */
	ioctl(jsd->fd, JSIOCGNAME(LINUX_JS_NAME_MAX), name);
	jsd->name = STRDUP(name);
#elif defined(__FreeBSD__)
	jsd->driver_version = version = 1;
	jsd->total_axises = axes = 2;
	jsd->total_buttons = buttons = 2;
	strlcpy(name, "FreeBSD-Gameport", LINUX_JS_NAME_MAX);
	jsd->name = STRDUP(name);
#endif
	/* Allocate axises */
	if(jsd->total_axises > 0)
	{
	    jsd->axis = (js_axis_struct **)calloc(
	        jsd->total_axises,
	        sizeof(js_axis_struct *)
	    );
	    if(jsd->axis == NULL)
	    {
	        jsd->total_axises = 0;
	        JSClose(jsd);
	        return(JSNoBuffers);
	    }
	}
	for(i = 0; i < jsd->total_axises; i++)
	{
	    jsd->axis[i] = axis = (js_axis_struct *)calloc(
		1, sizeof(js_axis_struct)
	    );
	    if(axis == NULL)
	    {
		JSClose(jsd);
		return(JSNoBuffers);
	    }

	    /* Reset axis values */
	    axis->cur = JSDefaultCenter;
	    axis->min = JSDefaultMin;
	    axis->max = JSDefaultMax;
	    axis->cen = JSDefaultCenter;
	    axis->nz = JSDefaultNullZone;
	    axis->tolorance = JSDefaultTolorance;
	    axis->flags = 0;
	}

	/* Allocate buttons */  
	if(jsd->total_buttons > 0)
	{
	    jsd->button = (js_button_struct **)calloc(
		jsd->total_buttons,
		sizeof(js_button_struct *)
	    );
	    if(jsd->button == NULL)   
	    {
		jsd->total_buttons = 0;
		JSClose(jsd);   
		return(JSNoBuffers);
	    }
	}
	for(i = 0; i < jsd->total_buttons; i++)
	{
	    jsd->button[i] = button = (js_button_struct *)calloc(
		1, sizeof(js_button_struct)
	    );
	    if(button == NULL)
	    {
		JSClose(jsd);
		return(JSNoBuffers);
	    }

	    /* Reset button values */
	    button->state = JSButtonStateOff;
	}

	/* Set to non-blocking? */
	if(flags & JSFlagNonBlocking)
	{
	    fcntl(jsd->fd, F_SETFL, O_NONBLOCK);
	    jsd->flags |= JSFlagNonBlocking;
 	}

	/* Mark successful initialization */
	jsd->flags |= JSFlagIsInit;

	/* Load calibration from calibration file */
	JSLoadCalibrationUNIX(jsd);

	/* Set axis tolorance for error correction */
	JSResetAllAxisTolorance(jsd);


	return(JSSuccess);
}
Example #4
0
/*
 *      Called by V3DGLProcessModelExtra() to process a model of type
 *      V3D_MODEL_TYPE_STANDARD.
 *
 *      Given inputs glres, glinterp, and m are assumed valid.
 */
static void V3DGLProcessModelStandard(
	v3d_glresource_struct *glres, v3d_glinterprite_struct *glinterp,
	v3d_model_struct *m,
	void *client_data,
	void (*extra_cb)(v3d_model_struct *, const char *, void *)
)
{       
	int pn, line_num;
	const char *line_ptr;   
	void *p;
	int matrix_level = 0;
	int texture_binded = FALSE;
	void *last_p_texture_orient = NULL;
	int coordinate_axis = V3D_GLCOORDINATE_AXIS_SCIENTIFIC;
	int flip_winding = FALSE;
	int pass_normals = V3D_GLPASS_NORMALS_AS_NEEDED;
	int unitlize_normals = TRUE;
	int pass_texcoords = V3D_GLPASS_TEXCOORDS_AS_NEEDED;
	int texture_name_case_sensitive = FALSE;
	int material_properties = V3D_GLPASS_MATERIAL_PROPERTIES_NEVER;
	int enable_blending = V3D_GLENABLE_BLENDING_NEVER;
	int faces = V3D_GLFACES_FRONT_AND_BACK;
	int blending_enabled = FALSE;
	int set_blend_func = FALSE;
	const char *heightfield_base_dir = NULL;
	const char *texture_base_dir = NULL;

	int last_begin_ptype = -1;

	mp_comment_struct *p_comment;
	mp_translate_struct *p_translate;
	mp_untranslate_struct *p_untranslate;
	mp_rotate_struct *p_rotate;
	mp_unrotate_struct *p_unrotate;
	mp_point_struct *p_point;
	mp_line_struct *p_line;
	mp_line_strip_struct *p_line_strip;
	mp_line_loop_struct *p_line_loop;
	mp_triangle_struct *p_triangle;
	mp_triangle_strip_struct *p_triangle_strip;
	mp_triangle_fan_struct *p_triangle_fan;
	mp_quad_struct *p_quad;
	mp_quad_strip_struct *p_quad_strip;
	mp_polygon_struct *p_polygon;
	mp_color_struct *p_color;
	mp_texture_select_struct *p_texture_select;
	mp_texture_orient_xy_struct *p_texture_orient_xy;
	mp_texture_orient_yz_struct *p_texture_orient_yz;
	mp_texture_orient_xz_struct *p_texture_orient_xz;
	mp_texture_off_struct *p_texture_off;
	mp_heightfield_load_struct *p_heightfield_load;


	/* Get some values GL interpritation structure (if set). */
	if(glinterp->flags & V3D_GLFLAG_COORDINATE_AXIS)
	    coordinate_axis = glinterp->coordinate_axis;
	if(glinterp->flags & V3D_GLFLAG_FLIP_WINDING)
	    flip_winding = glinterp->flip_winding;
	if(glinterp->flags & V3D_GLFLAG_PASS_NORMALS)
	    pass_normals = glinterp->pass_normals;
	if(glinterp->flags & V3D_GLFLAG_UNITLIZE_NORMALS)
	    unitlize_normals = glinterp->unitlize_normals;
	if(glinterp->flags & V3D_GLFLAG_PASS_TEXCOORDS)
	    pass_texcoords = glinterp->pass_texcoords;
	if(glinterp->flags & V3D_GLFLAG_TEXTURE_NAME_CASE_SENSITIVE)
	    texture_name_case_sensitive = glinterp->texture_name_case_sensitive;
	if(glinterp->flags & V3D_GLFLAG_MATERIAL_PROPERTIES)
	    material_properties = glinterp->material_properties;
	if(glinterp->flags & V3D_GLFLAG_FACES)
	    faces = glinterp->faces;
	if(glinterp->flags & V3D_GLFLAG_ENABLE_BLENDING)
	    enable_blending = glinterp->enable_blending;
	if(glinterp->flags & V3D_GLFLAG_SET_BLEND_FUNC)
	    set_blend_func = glinterp->set_blend_func;
	if(glinterp->flags & V3D_GLFLAG_HEIGHTFIELD_BASE_DIR)
	    heightfield_base_dir = glinterp->heightfield_base_dir;
	if(glinterp->flags & V3D_GLFLAG_TEXTURE_BASE_DIR)
	    texture_base_dir = glinterp->texture_base_dir;


	/* Iterate through each primitive on the given editor. */
	for(pn = 0; pn < m->total_primitives; pn++)
	{
	    p = m->primitive[pn];
	    if(p == NULL)
		continue;

	    /* Call glEnd() if last_begin_ptype does not match the
	     * new primitive type.
	     */
	    if((last_begin_ptype != V3DMPGetType(p)) &&
	       (last_begin_ptype > -1)
	    )
	    {
		glEnd();
		last_begin_ptype = -1;
	    }


	    /* Handle by primitive type. */
	    switch(V3DMPGetType(p))
	    {
	      case V3DMP_TYPE_COMMENT:
		p_comment = (mp_comment_struct *)p;
		for(line_num = 0; line_num < p_comment->total_lines; line_num++)
		{
		    line_ptr = (const char *)p_comment->line[line_num];
		    if(line_ptr == NULL)
			continue;

		    if(extra_cb != NULL)
			extra_cb(m, line_ptr, client_data);
		}
		break;

	      case V3DMP_TYPE_TRANSLATE:
		p_translate = (mp_translate_struct *)p;
		if(glinterp->flags & V3D_GLFLAG_ALLOW_TRANSLATIONS)
		{
		    if(!glinterp->allow_translations)
			break;
		}
		glPushMatrix();
		matrix_level++;

		switch(coordinate_axis)
		{
		  case V3D_GLCOORDINATE_AXIS_GL:
		    glTranslated(
			p_translate->x, p_translate->y, p_translate->z
		    );
		    break;

		  case V3D_GLCOORDINATE_AXIS_SCIENTIFIC:
		    glTranslated(
			p_translate->x, p_translate->z, -p_translate->y
		    );
		    break;
		}
		break;

	      case V3DMP_TYPE_UNTRANSLATE:
		p_untranslate = (mp_untranslate_struct *)p;
		if(glinterp->flags & V3D_GLFLAG_ALLOW_TRANSLATIONS)
		{
		    if(!glinterp->allow_translations)
			break;
		}
		glPopMatrix();
		matrix_level--;
		break;

	      case V3DMP_TYPE_ROTATE:
		p_rotate = (mp_rotate_struct *)p;
		if(glinterp->flags & V3D_GLFLAG_ALLOW_ROTATIONS)
		{
		    if(!glinterp->allow_rotations)
			break;
		}
		glPushMatrix();
		matrix_level++;

		switch(coordinate_axis)
		{
		  case V3D_GLCOORDINATE_AXIS_GL:
		    glRotated(
			-RADTODEG(p_rotate->heading),
			0.0, 0.0, 1.0
		    );
		    glRotated(
			-RADTODEG(p_rotate->pitch),
			1.0, 0.0, 0.0
		    );
		    glRotated(
		       -RADTODEG(p_rotate->bank),
			0.0, 1.0, 0.0
		    );
		    break;

		  case V3D_GLCOORDINATE_AXIS_SCIENTIFIC:
		    glRotated(
			-RADTODEG(p_rotate->heading),
			0.0, 1.0, 0.0
		    );
		    glRotated(
			-RADTODEG(p_rotate->pitch),
			1.0, 0.0, 0.0
		    );
		    glRotated(
		       -RADTODEG(p_rotate->bank),
			0.0, 0.0, 1.0
		    );
		    break;
		}
		break;

	      case V3DMP_TYPE_UNROTATE:
		p_unrotate = (mp_unrotate_struct *)p;
		if(glinterp->flags & V3D_GLFLAG_ALLOW_ROTATIONS)
		{
		    if(!glinterp->allow_rotations)
			break;
		}
		glPopMatrix();
		matrix_level--;
		break;

#define DO_SET_VERTEX_DYNAMIC	\
{ \
 int i; \
 mp_vertex_struct *v, *n, *tc; \
 mp_vertex_struct *fbn = NULL;	/* Fallback normal vector. */ \
\
 /* Look for first non-empty fallback normal vector. */ \
 if(pass_normals != V3D_GLPASS_NORMALS_NEVER) \
 { \
  for(i = 0; i < V_TOTAL; i++) \
  { \
   n = P_PTR->n[i]; \
   if(n != NULL) \
   { \
    if((n->x != 0.0) || (n->y != 0.0) || (n->z != 0.0)) \
     fbn = n; \
   } \
  } \
 } \
\
 if(flip_winding) \
 { \
  /* Check if we need to set the fallback normal for the first \
   * vertex. \
   */ \
  if((pass_normals != V3D_GLPASS_NORMALS_NEVER) && (V_TOTAL > 0)) \
  { \
   n = P_PTR->n[V_TOTAL - 1]; \
   if(n != NULL) \
   { \
    if((n->x == 0.0) && (n->y == 0.0) && (n->z == 0.0)) \
     V3DGLSetNormal(glinterp, fbn); \
   } \
  } \
 \
  for(i = V_TOTAL - 1; i >= 0; i--) \
  { \
   v = P_PTR->v[i]; \
   n = P_PTR->n[i]; \
   tc = P_PTR->tc[i]; \
   V3DGLSetNormal(glinterp, n); \
   V3DGLSetTexCoord(glinterp, v, tc, texture_binded, last_p_texture_orient); \
   V3DGLSetVertex(glinterp, v); \
  } \
 } \
 else \
 { \
  /* Check if we need to set the fallback normal for the first \
   * vertex. \
   */ \
  if((pass_normals != V3D_GLPASS_NORMALS_NEVER) && (V_TOTAL > 0)) \
  { \
   n = P_PTR->n[0]; \
   if(n != NULL) \
   { \
    if((n->x == 0.0) && (n->y == 0.0) && (n->z == 0.0)) \
     V3DGLSetNormal(glinterp, fbn); \
   } \
  } \
 \
  for(i = 0; i < V_TOTAL; i++) \
  { \
   v = P_PTR->v[i]; \
   n = P_PTR->n[i]; \
   tc = P_PTR->tc[i]; \
   V3DGLSetNormal(glinterp, n); \
   V3DGLSetTexCoord(glinterp, v, tc, texture_binded, last_p_texture_orient); \
   V3DGLSetVertex(glinterp, v); \
  } \
 } \
}

#define DO_SET_VERTEX_STATIC	\
{ \
 int i; \
 mp_vertex_struct *v, *n, *tc; \
 mp_vertex_struct *fbn = NULL; /* Fallback normal vector. */ \
\
 /* Look for first non-empty fallback normal vector. */ \
 if(pass_normals != V3D_GLPASS_NORMALS_NEVER) \
 { \
  for(i = 0; i < V_TOTAL; i++) \
  { \
   n = &P_PTR->n[i]; \
   if(n != NULL) \
   { \
    if((n->x != 0.0) || (n->y != 0.0) || (n->z != 0.0)) \
     fbn = n; \
   } \
  } \
 } \
\
 if(flip_winding) \
 { \
  /* Check if we need to set the fallback normal for the first \
   * vertex. \
   */ \
  if(pass_normals != V3D_GLPASS_NORMALS_NEVER) \
  { \
   n = &P_PTR->n[V_TOTAL - 1]; \
   if((n->x == 0.0) && (n->y == 0.0) && (n->z == 0.0)) \
    V3DGLSetNormal(glinterp, fbn); \
  } \
 \
  for(i = V_TOTAL - 1; i >= 0; i--) \
  { \
   v = &P_PTR->v[i]; \
   n = &P_PTR->n[i]; \
   tc = &P_PTR->tc[i]; \
   V3DGLSetNormal(glinterp, n); \
   V3DGLSetTexCoord(glinterp, v, tc, texture_binded, last_p_texture_orient); \
   V3DGLSetVertex(glinterp, v); \
  } \
 } \
 else \
 { \
  /* Check if we need to set the fallback normal for the first \
   * vertex. \
   */ \
  if(pass_normals != V3D_GLPASS_NORMALS_NEVER) \
  { \
   n = &P_PTR->n[0]; \
   if((n->x == 0.0) && (n->y == 0.0) && (n->z == 0.0)) \
    V3DGLSetNormal(glinterp, fbn); \
  } \
 \
  for(i = 0; i < V_TOTAL; i++) \
  { \
   v = &P_PTR->v[i]; \
   n = &P_PTR->n[i]; \
   tc = &P_PTR->tc[i]; \
   V3DGLSetNormal(glinterp, n); \
   V3DGLSetTexCoord(glinterp, v, tc, texture_binded, last_p_texture_orient); \
   V3DGLSetVertex(glinterp, v); \
  } \
 } \
}

	      case V3DMP_TYPE_POINT:
#define P_PTR	p_point
#define V_TOTAL	V3DMP_POINT_NVERTEX
		P_PTR = (mp_point_struct *)p;
		if(last_begin_ptype != V3DMP_TYPE_POINT)
		    glBegin(GL_POINTS);
		DO_SET_VERTEX_STATIC
		last_begin_ptype = V3DMP_TYPE_POINT;
#undef P_PTR
#undef V_TOTAL
		break;

	      case V3DMP_TYPE_LINE:
#define P_PTR   p_line
#define V_TOTAL V3DMP_LINE_NVERTEX
		P_PTR = (mp_line_struct *)p;
		if(last_begin_ptype != V3DMP_TYPE_LINE)
		    glBegin(GL_LINES);
		DO_SET_VERTEX_STATIC
		last_begin_ptype = V3DMP_TYPE_LINE;
#undef P_PTR
#undef V_TOTAL
		break;

	      case V3DMP_TYPE_LINE_STRIP:
#define P_PTR   p_line_strip
#define V_TOTAL P_PTR->total
		P_PTR = (mp_line_strip_struct *)p;
		glBegin(GL_LINE_STRIP);
		DO_SET_VERTEX_DYNAMIC
		glEnd();
#undef P_PTR
#undef V_TOTAL
		break;

	      case V3DMP_TYPE_LINE_LOOP:
#define P_PTR   p_line_loop
#define V_TOTAL P_PTR->total
		P_PTR = (mp_line_loop_struct *)p;
		glBegin(GL_LINE_LOOP);
		DO_SET_VERTEX_DYNAMIC
		glEnd();
#undef P_PTR
#undef V_TOTAL
		break;

	      case V3DMP_TYPE_TRIANGLE:
#define P_PTR   p_triangle
#define V_TOTAL V3DMP_TRIANGLE_NVERTEX
		P_PTR = (mp_triangle_struct *)p;
		if(last_begin_ptype != V3DMP_TYPE_TRIANGLE)
		    glBegin(GL_TRIANGLES);
		DO_SET_VERTEX_STATIC
		last_begin_ptype = V3DMP_TYPE_TRIANGLE;
#undef P_PTR
#undef V_TOTAL
		break;

	      case V3DMP_TYPE_TRIANGLE_STRIP:
#define P_PTR   p_triangle_strip
#define V_TOTAL P_PTR->total
		P_PTR = (mp_triangle_strip_struct *)p;
		glBegin(GL_TRIANGLE_STRIP);
		DO_SET_VERTEX_DYNAMIC
		glEnd();
#undef P_PTR
#undef V_TOTAL
		break;

	      case V3DMP_TYPE_TRIANGLE_FAN:
#define P_PTR   p_triangle_fan
#define V_TOTAL P_PTR->total
		P_PTR = (mp_triangle_fan_struct *)p;
		glBegin(GL_TRIANGLE_FAN);
		DO_SET_VERTEX_DYNAMIC
		glEnd();
#undef P_PTR
#undef V_TOTAL
		break;

	      case V3DMP_TYPE_QUAD:
#define P_PTR   p_quad
#define V_TOTAL V3DMP_QUAD_NVERTEX
		P_PTR = (mp_quad_struct *)p;
		if(last_begin_ptype != V3DMP_TYPE_QUAD)
		    glBegin(GL_QUADS);
		DO_SET_VERTEX_STATIC
		last_begin_ptype = V3DMP_TYPE_QUAD;
#undef P_PTR
#undef V_TOTAL
		break;

	      case V3DMP_TYPE_QUAD_STRIP:
#define P_PTR   p_quad_strip
#define V_TOTAL P_PTR->total
		P_PTR = (mp_quad_strip_struct *)p;
		glBegin(GL_QUAD_STRIP);
		DO_SET_VERTEX_DYNAMIC
		glEnd();
#undef P_PTR
#undef V_TOTAL
		break;

	      case V3DMP_TYPE_POLYGON:
#define P_PTR   p_polygon
#define V_TOTAL P_PTR->total
		P_PTR = (mp_polygon_struct *)p;
		glBegin(GL_POLYGON);
		DO_SET_VERTEX_DYNAMIC
		glEnd();
#undef P_PTR
#undef V_TOTAL
		break;

#undef DO_SET_VERTEX_STATIC
#undef DO_SET_VERTEX_DYNAMIC


	      case V3DMP_TYPE_COLOR:
		p_color = (mp_color_struct *)p;
		if(p_color->a < 1.0)
		{
		    if(enable_blending)
		    {
			if(!blending_enabled)
			{
			    glEnable(GL_BLEND);
			    glDisable(GL_ALPHA_TEST);
			    blending_enabled = TRUE;
			}
		    }
		    if(set_blend_func)
		    {
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		    }
		}
		else
		{
		    if(enable_blending)
		    {
			if(blending_enabled)
			{   
			    glDisable(GL_BLEND);
			    glEnable(GL_ALPHA_TEST);
			    blending_enabled = FALSE;
			}
		    }
		}
		/* Set color? */
		if(material_properties != V3D_GLPASS_MATERIAL_PROPERTIES_INSTEAD_COLOR)
		{
		    glColor4d(p_color->r, p_color->g, p_color->b, p_color->a);
		}
		/* Set material properties? */
		if(material_properties != V3D_GLPASS_MATERIAL_PROPERTIES_NEVER)
		{
		    GLenum glface;
		    GLfloat glparam[4];

		    switch(faces)
		    {
		      case V3D_GLFACES_FRONT_AND_BACK:
			glface = GL_FRONT_AND_BACK;
			break;
		      case V3D_GLFACES_BACK:
			glface = GL_BACK;
			break;
		      default:	/* V3D_GLFACES_FRONT */
			glface = GL_FRONT;
			break;
		    }

		    glparam[0] = (GLfloat)(p_color->ambient * p_color->r);
		    glparam[1] = (GLfloat)(p_color->ambient * p_color->g);
		    glparam[2] = (GLfloat)(p_color->ambient * p_color->b);
		    glparam[3] = (GLfloat)(p_color->a);
		    glMaterialfv(glface, GL_AMBIENT, glparam);

		    glparam[0] = (GLfloat)(p_color->diffuse * p_color->r);
		    glparam[1] = (GLfloat)(p_color->diffuse * p_color->g);
		    glparam[2] = (GLfloat)(p_color->diffuse * p_color->b);
		    glparam[3] = (GLfloat)(p_color->a);
		    glMaterialfv(glface, GL_DIFFUSE, glparam);

		    glparam[0] = (GLfloat)(p_color->specular * p_color->r);
		    glparam[1] = (GLfloat)(p_color->specular * p_color->g);
		    glparam[2] = (GLfloat)(p_color->specular * p_color->b);
		    glparam[3] = (GLfloat)(p_color->a);
		    glMaterialfv(glface, GL_SPECULAR, glparam);

		    glparam[0] = (GLfloat)(p_color->shininess * 128.0);
		    glMaterialf(glface, GL_SHININESS, glparam[0]);
 
		    glparam[0] = (GLfloat)(p_color->emission * p_color->r);
		    glparam[1] = (GLfloat)(p_color->emission * p_color->g);
		    glparam[2] = (GLfloat)(p_color->emission * p_color->b);
		    glparam[3] = (GLfloat)(p_color->a);
		    glMaterialfv(glface, GL_EMISSION, glparam);
		}
		break;

	      case V3DMP_TYPE_TEXTURE_SELECT:
		p_texture_select = (mp_texture_select_struct *)p;
		if(p_texture_select->name != NULL)
		{
		    const char *tex_name = (const char *)p_texture_select->name;
		    int tn;
		    v3d_texture_ref_struct *t;

		    /* Previous last_p_texture_orient gets reset when
		     * a new texture is binded.
		     */
		    last_p_texture_orient = NULL;

		    /* Iterate through each loaded texture on the 
		     * gl resources structure.
		     */
		    for(tn = 0; tn < glres->total_textures; tn++)
		    {
			t = glres->texture[tn];
			if((t == NULL) ? 1 : (t->name == NULL))
			    continue;

			if(texture_name_case_sensitive)
			{
			    if(!strcmp(t->name, tex_name))
				break;
			}
			else
			{
			    if(!strcasecmp(t->name, tex_name))
				break;
			}
		    }
		    /* Matched texture? */
		    if(tn < glres->total_textures)
			t = glres->texture[tn];
		    else
			t = NULL;

		    if(t == NULL)
		    {
			/* No texture, unbind any existing texture. */
			V3DTextureSelect(NULL);
			texture_binded = FALSE;
		    }
		    else
		    {
			V3DTextureSelect(t);
			texture_binded = TRUE;
		    }
		}
		break;

	      case V3DMP_TYPE_TEXTURE_ORIENT_XY:
		p_texture_orient_xy = (mp_texture_orient_xy_struct *)p;
		if(texture_binded)
		{
		    last_p_texture_orient = p;
		}
		break;

	      case V3DMP_TYPE_TEXTURE_ORIENT_YZ:
		p_texture_orient_yz = (mp_texture_orient_yz_struct *)p;
		if(texture_binded)
		{
		    last_p_texture_orient = p;
		}
		break;

	      case V3DMP_TYPE_TEXTURE_ORIENT_XZ:
		p_texture_orient_xz = (mp_texture_orient_xz_struct *)p;
		if(texture_binded)
		{
		    last_p_texture_orient = p;
		}
		break;

	      case V3DMP_TYPE_TEXTURE_OFF:
		p_texture_off = (mp_texture_off_struct *)p;
		V3DTextureSelect(NULL);
		texture_binded = FALSE;
		last_p_texture_orient = NULL;
		break;

	      case V3DMP_TYPE_HEIGHTFIELD_LOAD:
		p_heightfield_load = (mp_heightfield_load_struct *)p;
		if(p_heightfield_load->path != NULL)
		{
		    int status, widthp, heightp;
		    double x_spacing, y_spacing;
		    const char *cstrptr;
		    v3d_hf_options_struct hfopt;
		    char tmp_path[PATH_MAX + NAME_MAX];

		    if(ISPATHABSOLUTE(p_heightfield_load->path))
		    {
			strncpy(tmp_path, p_heightfield_load->path, PATH_MAX + NAME_MAX);
		    }
		    else if(heightfield_base_dir != NULL)
		    {
			cstrptr = (const char *)PrefixPaths(
			    heightfield_base_dir, p_heightfield_load->path
			);
			strncpy(
			    tmp_path,
			    (cstrptr == NULL) ? p_heightfield_load->path : cstrptr,
			    PATH_MAX + NAME_MAX
			);
		    }
		    else
		    {
			strncpy(tmp_path, p_heightfield_load->path, PATH_MAX + NAME_MAX);
		    }

		    glPushMatrix();
		    switch(coordinate_axis)
		    {
		      case V3D_GLCOORDINATE_AXIS_GL:
			glTranslated(
			    p_heightfield_load->x,
			    p_heightfield_load->y,
			    p_heightfield_load->z
			);
			glRotated(
			    -RADTODEG(p_heightfield_load->heading),
			    0.0, 0.0, 1.0 
			);
			glRotated(
			    -RADTODEG(p_heightfield_load->pitch),  
			    1.0, 0.0, 0.0
			);
			glRotated(
			    -RADTODEG(p_heightfield_load->bank),
			    0.0, 1.0, 0.0
			);
			break;

		      case V3D_GLCOORDINATE_AXIS_SCIENTIFIC:
			glTranslated(
			    p_heightfield_load->x, 
			    p_heightfield_load->z,
			    -p_heightfield_load->y
			);
			glRotated(
			    -RADTODEG(p_heightfield_load->heading),
			    0.0, 1.0, 0.0
			);
			glRotated(
			    -RADTODEG(p_heightfield_load->pitch),
			    1.0, 0.0, 0.0
			);
			glRotated(
			    -RADTODEG(p_heightfield_load->bank),
			    0.0, 0.0, 1.0
			);
			break;
		    }

		    /* Set up heightfield options. */
		    hfopt.flags = (V3D_HF_OPT_FLAG_WINDING |
			V3D_HF_OPT_FLAG_SET_NORMAL | V3D_HF_OPT_FLAG_SET_TEXCOORD
		    );
		    hfopt.winding = ((flip_winding) ?
			V3D_HF_WIND_CCW : V3D_HF_WIND_CW
		    );
		    hfopt.set_normal = ((pass_normals != V3D_GLPASS_NORMALS_NEVER) ?
			V3D_HF_SET_NORMAL_AVERAGED : V3D_HF_SET_NORMAL_NEVER
		    );
		    hfopt.set_texcoord = ((pass_texcoords != V3D_GLPASS_TEXCOORDS_NEVER) ?
			V3D_HF_SET_TEXCOORD_ALWAYS : V3D_HF_SET_TEXCOORD_NEVER
		    );

		    /* Load heightfield from image file and generate GL
		     * commands.
		     */
		    status = V3DHFLoadFromFile(
			tmp_path,
			p_heightfield_load->x_length, 
			p_heightfield_load->y_length,
			p_heightfield_load->z_length,
			&widthp, &heightp,
			&x_spacing, &y_spacing,
			NULL,		/* No allocated z points. */
			NULL,		/* GL list not important. */
			&hfopt
		    );
		    glPopMatrix();
		}
		break;
	    }
	}

	/* Need to call glEnd() if last_begin_ptype is not -1. */
	if(last_begin_ptype > -1)
	{
	    glEnd();
	    last_begin_ptype = -1;
	}

	/* Pop any extranous matrixes */
	while(matrix_level > 0)
	{
	    glPopMatrix();
	    matrix_level--;
	}

	/* Unbind any textures */
	if(texture_binded)
	    V3DTextureSelect(NULL);

	/* Restore blend state */
	if(blending_enabled)
	{
	    glDisable(GL_BLEND);
	    glEnable(GL_ALPHA_TEST);
	    blending_enabled = FALSE;
	}
}
Example #5
0
/*
 *	Allocates a new gl resources structure with the values
 *	initialized with respect to the given V3D model data.
 *
 *	If the given v3d_glinterprite_struct *glinterp is not NULL then
 *	its values will be coppied to the new gl resources structure
 *	and overrides any values defined in the model header items.
 *
 *      The correct gl context must be binded before calling this
 *      function.
 */
v3d_glresource_struct *V3DGLResourceNewFromModelData(
	const v3d_glinterprite_struct *glinterp,
	void **mh_item, int total_mh_items,
	v3d_model_struct **model, int total_models
)
{
	int i, n;
	unsigned int interp_flags;
	int tex_dest_fmt = V3D_TEX_FORMAT_RGBA;
	void *h;
	mh_texture_load_struct *h_texture_load;
	const char *texture_base_dir;
	v3d_glresource_struct *glres = V3DGLResourceNew();


	if(glres == NULL)
	    return(NULL);

	/* Get interpritation flags that define what values that are set
	 * in the gl interpritation structure.
	 */
	interp_flags = (glinterp != NULL) ? glinterp->flags : 0;

	/* Get texture base directory. */
	texture_base_dir = (const char *)V3DMHTextureBaseDirectoryGet(
	    mh_item, total_mh_items
	);
	/* Interpritation structure overrides? */
	if(interp_flags & V3D_GLFLAG_TEXTURE_BASE_DIR)
	    texture_base_dir = glinterp->texture_base_dir;


	/* Load textures by iterating through model header items. */
	for(i = 0; i < total_mh_items; i++)
	{
	    h = mh_item[i];
	    if(h == NULL)
		continue;

	    /* This header item specify a texture load? */
	    if((*(int *)h) == V3DMH_TYPE_TEXTURE_LOAD)
	    {
		v3d_texture_ref_struct *t;
		char tmp_path[PATH_MAX + NAME_MAX];


		h_texture_load = (mh_texture_load_struct *)h;

		if(h_texture_load->path == NULL)
		    continue;

		if(ISPATHABSOLUTE(h_texture_load->path))
		{
		    strncpy(tmp_path, h_texture_load->path, PATH_MAX + NAME_MAX);
		}
                else 
                {
                    const char *cstrptr = PrefixPaths(dname.local_data,h_texture_load->path);
                    struct stat stat_buf;
                    if((cstrptr != NULL) ? stat(cstrptr, &stat_buf) : 1)
                        cstrptr = PrefixPaths(dname.global_data, h_texture_load->path);
                    strncpy(tmp_path,cstrptr,PATH_MAX + NAME_MAX);
                }
		/* else if(texture_base_dir != NULL) */
		/* { */
		/*     const char *cstrptr = (const char *)PrefixPaths( */
		/* 	texture_base_dir, h_texture_load->path */
		/*     ); */
		/*     if(cstrptr == NULL) */
		/* 	continue; */

		/*     strncpy(tmp_path, cstrptr, PATH_MAX + NAME_MAX); */
		/* } */
		/* else */
		/* { */
		/*     strncpy(tmp_path, h_texture_load->path, PATH_MAX + NAME_MAX); */
		/* } */
		tmp_path[PATH_MAX + NAME_MAX - 1] = '\0';


		t = V3DTextureLoadFromFile2D(
		    tmp_path,
		    h_texture_load->name,
		    tex_dest_fmt,
		    NULL, NULL
		);
		if(t != NULL)
		{
		    /* Texture loaded successfully. */

		    /* Set texture priority. */
		    V3DTexturePriority(t, h_texture_load->priority);

		    /* Allocate more texture pointers on GL resource. */
		    n = glres->total_textures;
		    glres->total_textures = n + 1;
		    glres->texture = (v3d_texture_ref_struct **)realloc(
			glres->texture,
			glres->total_textures * sizeof(v3d_texture_ref_struct *)
		    );
		    if(glres->texture == NULL)
		    {
			glres->total_textures = 0;
			V3DTextureDestroy(t);
			break;
		    }

		    glres->texture[n] = t;
		    t = NULL;
		}
	    }
	}


	/* Override any GL interpritation values? */
	if(glinterp != NULL)
	    V3DGLResourceSetInterpritation(glres, glinterp);

	return(glres);
}
Example #6
0
/*
 *	Called by CPLoadFromFile().
 *
 *	Loads an instrument configuration file that will set up values
 *	specific to that instrument.
 *
 *	Returns non-zero on error.
 */
static int CPLoadInstrumentFromFile(
	ControlPanel *cp, const char *path,
	CPIns *ins, int ins_num,
	const char *filename
)
{
	int handled_parm;
        FILE            *fp;
        char            *buf = NULL;
        struct stat     stat_buf;


        if((cp == NULL) || (filename == NULL))
            return(-1);

        if(*filename == '\0')
            return(-1);

	/* No instrument in context? */
	if(ins == NULL)
	{
            fprintf(stderr, "%s: No instrument in context.\n", filename);
            return(-1);
        }

	/* Check if file exists. */
        if(stat(filename, &stat_buf))
        {
            fprintf(stderr, "%s: No such file.\n", filename);
            return(-1);
        }

        /* Open instrument configuration file. */
        fp = FOpen(filename, "rb");
        if(fp == NULL)
        {
            fprintf(stderr, "%s: Cannot open.\n", filename);
            return(-1);
        }

        /* Begin reading instruent configuration file. */
        do
        {
            buf = FSeekNextParm(
                fp,
                buf,
                SAR_COMMENT_CHAR,
                SAR_CFG_DELIM_CHAR
            );
	    if(buf == NULL)
		break;

	    handled_parm = 0;

            /* Version */
            if(!strcasecmp(buf, "Version"))
            {
                double vf[2];
                FGetValuesF(fp, vf, 2);

                /* Ignore. */
		handled_parm++;
            }

	    /* Resolution */
	    else if(!strcasecmp(buf, "Resolution"))
            {
		int res_width, res_height;
                double vf[2];
                FGetValuesF(fp, vf, 2);
		res_width = (int)vf[0];
		res_height = (int)vf[1];
		if(res_width < 2)
		{
		    fprintf(
			stderr,
"%s: Resolution: Error: Width %i cannot be less than 2 (must be a 2^x value).\n",
			filename, res_width
		    );
		    res_width = 2;
		}
                if(res_height < 2)
                {
                    fprintf(
                        stderr,
"%s: Resolution: Error: Height %i cannot be less than 2 (must be a 2^x value).\n",
                        filename, res_height
                    );
                    res_width = 2;
                }
		CPInsSetResolution(ins, res_width, res_height);
		handled_parm++;
	    }

            /* TextureBackground */
            else if(!strcasecmp(buf, "TextureBackground") ||
                    !strcasecmp(buf, "TextureBG")
	    )
            {
                char *s = FGetString(fp);
                if(!ISPATHABSOLUTE(s))
                {
                    char *s2 = STRDUP(PrefixPaths(path, s));
                    free(s);
                    s = s2;
                }
		CPInsSetTextureBG(ins, s);
                free(s);
                handled_parm++;
	    }

            /* TextureForeground */
            else if(!strcasecmp(buf, "TextureForeground") ||
                    !strcasecmp(buf, "TextureFG")
            )
            {
                char *s = FGetString(fp);
                if(!ISPATHABSOLUTE(s))
                {
                    char *s2 = STRDUP(PrefixPaths(path, s));
                    free(s);
                    s = s2;
                }
                CPInsSetTextureFG(ins, s);
                free(s);
                handled_parm++;
            }

            /* ColorBackgroundNormal */
            else if(!strcasecmp(buf, "ColorBackgroundNormal") ||
                    !strcasecmp(buf, "ColorBGNormal")
            )
            {
		CPColor *c = &ins->color_bg[CP_COLOR_STATE_NORMAL];
                double vf[3];
                FGetValuesF(fp, vf, 3);
		c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0);
                c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0);
                c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0);
                handled_parm++;
            }
            /* ColorBackgroundDim */
            else if(!strcasecmp(buf, "ColorBackgroundDim") ||
                    !strcasecmp(buf, "ColorBGDim")
            )
            {
                CPColor *c = &ins->color_bg[CP_COLOR_STATE_DIM];
                double vf[3];
                FGetValuesF(fp, vf, 3);
                c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0);
                c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0);
                c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0);
                handled_parm++;
            }
            /* ColorBackgroundDark */
            else if(!strcasecmp(buf, "ColorBackgroundDark") ||
                    !strcasecmp(buf, "ColorBGDark")
            )
            {
                CPColor *c = &ins->color_bg[CP_COLOR_STATE_DARK];
                double vf[3];
                FGetValuesF(fp, vf, 3);
                c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0);
                c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0);
                c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0);
                handled_parm++;
            }
            /* ColorBackgroundLighted */
            else if(!strcasecmp(buf, "ColorBackgroundLighted") ||
                    !strcasecmp(buf, "ColorBGLighted")
            )
            {
                CPColor *c = &ins->color_bg[CP_COLOR_STATE_LIGHTED];
                double vf[3];
                FGetValuesF(fp, vf, 3);
                c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0);
                c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0);
                c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0);
                handled_parm++;
            }

            /* ColorForegroundNormal */
            else if(!strcasecmp(buf, "ColorForegroundNormal") ||
                    !strcasecmp(buf, "ColorFGNormal")
            )
            {
                CPColor *c = &ins->color_fg[CP_COLOR_STATE_NORMAL];
                double vf[3];
                FGetValuesF(fp, vf, 3);
                c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0);
                c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0);
                c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0);
                handled_parm++;
            }
            /* ColorForegroundDim */
            else if(!strcasecmp(buf, "ColorForegroundDim") ||
                    !strcasecmp(buf, "ColorFGDim")
            )
            {
                CPColor *c = &ins->color_fg[CP_COLOR_STATE_DIM];
                double vf[3];
                FGetValuesF(fp, vf, 3);
                c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0);
                c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0);
                c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0);
                handled_parm++;
            }
            /* ColorForegroundDark */
            else if(!strcasecmp(buf, "ColorForegroundDark") ||
                    !strcasecmp(buf, "ColorFGDark")
            )
            {
                CPColor *c = &ins->color_fg[CP_COLOR_STATE_DARK];
                double vf[3];
                FGetValuesF(fp, vf, 3);
                c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0);
                c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0);
                c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0);
                handled_parm++;
            }
            /* ColorForegroundLighted */
            else if(!strcasecmp(buf, "ColorForegroundLighted") ||
                    !strcasecmp(buf, "ColorFGLighted")
            )
            {
                CPColor *c = &ins->color_fg[CP_COLOR_STATE_LIGHTED];
                double vf[3];
                FGetValuesF(fp, vf, 3);
                c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0);
                c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0);
                c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0);
                handled_parm++;
            }

            /* ColorTextNormal */
            else if(!strcasecmp(buf, "ColorTextNormal"))
            {
                CPColor *c = &ins->color_text[CP_COLOR_STATE_NORMAL];
                double vf[3];
                FGetValuesF(fp, vf, 3);
                c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0);
                c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0);
                c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0);
                handled_parm++;
            }
            /* ColorTextDim */
            else if(!strcasecmp(buf, "ColorTextDim"))
            {
                CPColor *c = &ins->color_text[CP_COLOR_STATE_DIM];
                double vf[3];
                FGetValuesF(fp, vf, 3);
                c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0);
                c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0);
                c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0);
                handled_parm++;
            }
            /* ColorTextDark */
            else if(!strcasecmp(buf, "ColorTextDark"))
            {
                CPColor *c = &ins->color_text[CP_COLOR_STATE_DARK];
                double vf[3];
                FGetValuesF(fp, vf, 3);
                c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0);
                c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0);
                c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0);
                handled_parm++;
            }
            /* ColorTextLighted */
            else if(!strcasecmp(buf, "ColorTextLighted"))
            {
                CPColor *c = &ins->color_text[CP_COLOR_STATE_LIGHTED];
                double vf[3];
                FGetValuesF(fp, vf, 3);
                c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0);
                c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0);
                c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0);
                handled_parm++;
            }

	    /* If the parameter was not handled then pass it to an
	     * instrument specific handler.
	     */
	    if(handled_parm <= 0)
	    {
		/* Call instrument specific loading function to
		 * deal with this parameter.
		 */
		switch(CPINS_TYPE(ins))
		{
                  case CPINS_TYPE_ALTIMETER:
                    handled_parm += CPLoadInstrumentAltimeter(
                        fp, ins, buf
                    );
                    break;
                  case CPINS_TYPE_BEARING:
                    handled_parm += CPLoadInstrumentBearing(
                        fp, ins, buf
                    );
                    break;
		  case CPINS_TYPE_HORIZON:
		    handled_parm += CPLoadInstrumentHorizon(
			fp, ins, buf
		    );
		    break;
		}
		/* Parameter still not handled? */
		if(handled_parm <= 0)
		{
		    fprintf(
			stderr,
			"%s: Unsupported parameter `%s'.\n",
			filename, buf
		    );
		    FSeekNextLine(fp);
		}
            }

        } while(1);

        /* Close instrument configuration file. */
        FClose(fp);

        return(0);
}