/* * 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); }
/* * 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); }
/* * 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); }
/* * 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; } }
/* * 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); }
/* * 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); }