home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 41
/
Amiga_Dream_41.iso
/
Amiga
/
Pro
/
3d
/
ICoons1_0.lzh
/
icoons
/
source
/
file.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-10-25
|
19KB
|
773 lines
/* :ts=8 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include "general.h"
#include "globals.h"
#include "intui.h"
#include "spl_util.h"
#include "file.h"
#define Size_JMan_Point_Table 1000
static int JMan_Point_Table_Idx;
static short *JMan_Point_Table;
void StrTrim(char *Out, char *In)
/************************************************************************/
/* */
/* Remove leading and trailing spaces from In, and copy to Out. */
/* */
/************************************************************************/
{
int Last, i, j;
if (In[0] == '\0') {
Out[0] = '\0';
return;
} /* if */
for (Last = strlen(In)-1; isspace(In[Last]); Last--) ;
for (i = 0; isspace(In[i]); i++) ;
for (j=0; i <= Last; i++,j++) Out[j] = In[i];
Out[j] = '\0';
} /* StrTrim */
static
Boolean_T Read_Line(FILE *Stream, char *Line)
/************************************************************************/
/* */
/* Read next line from stream 'Stream'. Return it in 'Line'. */
/* Ignore blank lines and lines starting with '#'. */
/* */
/* The function will return TRUE in case of error or eof. */
/* */
/************************************************************************/
{
while (fgets(Line, Buffer_Length, Stream) != NULL) {
Line[Buffer_Length] = '\0';
StrTrim(Line, Line);
if (Line[0] != '#' && Line[0] != '\0') return(FALSE);
} /* while */
return(TRUE);
} /* Read_Line */
static
void Display_Open_Error_Msg(char *Filename)
/************************************************************************/
/* */
/* */
/************************************************************************/
{
sprintf(Error_Msg, "Couldn't open %s", Filename);
Display_Message(Error_Msg);
} /* Display_Open_Error_Msg */
Boolean_T Object_File_Write(char *Filename)
/************************************************************************/
/* */
/* */
/************************************************************************/
{
FILE *Stream;
Spline_T *Spline;
Knot_T *Knot;
int i, j;
Stream = fopen(Filename, "w");
if (Stream == NULL) {
Display_Open_Error_Msg(Filename);
return(TRUE);
}
Display_Status("Saving object...");
Set_Pointer(TRUE);
fprintf(Stream, "#\n");
fprintf(Stream, "# Patches created by ICoons\n");
fprintf(Stream, "#\n");
fprintf(Stream, "#\n");
fprintf(Stream, "#--------------------------------------------------\n");
fprintf(Stream, "# Points:\n");
fprintf(Stream, "#--------------------------------------------------\n");
fprintf(Stream, "#\n");
for (i = 0; i < Max_Nbr_Points; i++) {
if (Points[i].Reference_Count > 0) {
fprintf(Stream, "P %d %d %lf %lf %lf\n",
i,
Points[i].Reference_Count,
Points[i].Pos[0],
Points[i].Pos[1],
Points[i].Pos[2]);
} /* if */
} /* for */
fprintf(Stream, "#\n");
fprintf(Stream, "#--------------------------------------------------\n");
fprintf(Stream, "# Splines:\n");
fprintf(Stream, "#--------------------------------------------------\n");
fprintf(Stream, "#\n");
for (Spline = Splines; Spline != NULL; Spline = Spline->Next) {
if (Spline->Nbr_Knots > 0) {
fprintf(Stream, "S %d %d\n",
Spline->Nbr_Knots,
Spline->Loop);
for (j = 0, Knot = Spline->First;
j < Spline->Nbr_Knots; j++, Knot = Knot->Next) {
fprintf(Stream, "K %d %lf %lf %lf\n",
Knot->Point_Id,
Knot->Tension,
Knot->Bias,
Knot->Continuity);
} /* for */
fprintf(Stream, "#\n");
fprintf(Stream,
"#--------------------------------------------------\n");
fprintf(Stream, "#\n");
} /* if */
} /* for */
fclose(Stream);
Set_Pointer(FALSE);
Display_Status(NULL);
return(FALSE);
} /* Object_File_Write */
Boolean_T Object_File_Read(char *Filename)
/************************************************************************/
/* */
/* */
/************************************************************************/
{
FILE *Stream;
char Line[Buffer_Length+1];
Spline_T *Spline;
Knot_T *Knot;
int Point_Id;
int New_Point_Id;
int Reference_Count;
Vector_T Pos;
int Nbr_Knots;
int Loop;
double Tension, Bias, Continuity;
Knot = NULL;
Spline = NULL;
Stream = fopen(Filename, "r");
if (Stream == NULL) {
Display_Open_Error_Msg(Filename);
return(TRUE);
}
Display_Status("Loading object...");
Set_Pointer(TRUE);
for (Point_Id = 0; Point_Id < Max_Nbr_Points; Point_Id++)
Points[Point_Id].Work = -1;
while (! Read_Line(Stream, Line)) {
if (Line[0] == 'P') { /* Point: */
sscanf(Line, "P %d %d %lf %lf %lf",
&Point_Id,
&Reference_Count,
&Pos[0], &Pos[1], &Pos[2]);
if (Point_Id >= 0 && Point_Id < Max_Nbr_Points) {
New_Point_Id = Point_New(Pos);
if (New_Point_Id < 0) {
Display_Message("No more space for points.");
Set_Pointer(FALSE);
fclose(Stream);
return(TRUE);
}
Points[Point_Id].Work = New_Point_Id;
} /* if */
} /* if */
if (Line[0] == 'S') { /* Spline start : */
sscanf(Line, "S %d %d", &Nbr_Knots, &Loop);
Spline = Spline_New();
if (Spline == NULL) {
Display_Message("Couldn't allocate memory for new spline");
Set_Pointer(FALSE);
fclose(Stream);
return(TRUE);
}
Spline->Flags = 0;
Spline->Nbr_Knots = 0;
Spline_Loop(Spline, Loop);
Knot = NULL;
} /* if */
if (Line[0] == 'K') { /* Knot : */
sscanf(Line, "K %d %lf %lf %lf",
&Point_Id,
&Tension,
&Bias,
&Continuity);
if (Spline != NULL) {
Knot = Knot_New(Spline, Knot);
if (Knot == NULL) {
Display_Message("Couldn't allocate memory for new knot");
Set_Pointer(FALSE);
fclose(Stream);
return(TRUE);
} /* if */
if (Point_Id < 0 || Point_Id >= Max_Nbr_Points) {
Display_Message("Invalid point id in file");
Set_Pointer(FALSE);
fclose(Stream);
return(TRUE);
}
/* We have probably moved this point to another position */
/* Get new point id. */
New_Point_Id = Points[Point_Id].Work;
if (New_Point_Id < 0 || New_Point_Id >= Max_Nbr_Points) {
Display_Message("Inconsistent point id in file");
Set_Pointer(FALSE);
fclose(Stream);
return(TRUE);
}
Knot->Point_Id = New_Point_Id;
Knot->Tension = Tension;
Knot->Bias = Bias;
Knot->Continuity = Continuity;
Knot->Flags = 0;
Points[New_Point_Id].Reference_Count++;
} /* if */
} /* if */
} /* while */
fclose(Stream);
Display_Status(NULL);
Set_Pointer(FALSE);
return(FALSE);
} /* Object_File_Read */
static
Boolean_T JMan_Header_Read(FILE *Stream, int *Nbr_Splines)
/************************************************************************/
/* */
/* */
/************************************************************************/
{
char Line[Buffer_Length+1];
if (Read_Line(Stream, Line)) goto Eof;
if (strncmp(Line, "SCUL", 4) != 0) {
Display_Message("Not a Journeyman .seg file");
return(TRUE);
} /* if */
if (Read_Line(Stream, Line)) goto Eof; /* A */
if (Read_Line(Stream, Line)) goto Eof; /* MinPos MaxPos */
if (Read_Line(Stream, Line)) goto Eof; /* Pos */
if (Read_Line(Stream, Line)) goto Eof; /* Nbr_Splines */
*Nbr_Splines = atoi(Line);
if (*Nbr_Splines < 1) {
sprintf(Error_Msg, "Number of splines (%s) out of range", Line);
Display_Message(Error_Msg);
return(TRUE);
} /* if */
return(FALSE);
Eof:
Display_Message("Eof before expected");
fclose(Stream);
return(TRUE);
} /* JMan_Header_Read */
static
Boolean_T JMan_Knot_Read(FILE *Stream, Spline_T *Spline, Knot_T **Knot,
int *Nbr_Points)
/************************************************************************/
/* */
/* */
/************************************************************************/
{
char Line[Buffer_Length+1];
int i1, i2, i3;
int Idx;
double X, Y, Z;
double Tension, Bias, Continuity;
double Alfa1, Gamma1, Magnitude1;
double Alfa2, Gamma2, Magnitude2;
JMan_Point_Table_Idx++;
if (Read_Line(Stream, Line)) goto Eof; /* i1 i2 i3 */
sscanf(Line, "%d %d %d", &i1, &i2, &i3);
if ((i1 != 0 && i1 != 1 && i1 != 4 && i1 != 5) ||
(i2 != 8) ||
(i3 != 0 && i3 != 1)) {
sprintf(Error_Msg, "Format error in line \n'%s'", Line);
Display_Message(Error_Msg);
return(TRUE);
} /* if */
if (i1 & 4) Spline_Loop(Spline, TRUE);
if (Read_Line(Stream, Line)) goto Eof; /* Pos or id */
if (i3 == 0) {
sscanf(Line, "%lf %lf %lf",&X, &Y, &Z);
if (*Nbr_Points >= Max_Nbr_Points - 1) {
Display_Message("Too many points");
return(TRUE);
} /* if */
Points[*Nbr_Points].Reference_Count = 0;
Points[*Nbr_Points].Flags = 0;
Points[*Nbr_Points].Pos[0] = X;
Points[*Nbr_Points].Pos[1] = Y;
Points[*Nbr_Points].Pos[2] = Z;
Idx = JMan_Point_Table_Idx;
JMan_Point_Table[Idx] = *Nbr_Points;
*Nbr_Points += 1;
} else {
sscanf(Line, "%d",&Idx);
JMan_Point_Table[JMan_Point_Table_Idx] = -Idx;
if (Idx < 1 || Idx >= Size_JMan_Point_Table) {
sprintf(Error_Msg, "Invalid point id %d)", Idx);
Display_Message(Error_Msg);
return(TRUE);
} /* if */
} /* if .. else .. */
*Knot = Knot_New(Spline, *Knot);
if (*Knot == NULL) {
Display_Message("Couldn't allocate memory for new knot");
return(TRUE);
} /* if */
(*Knot)->Point_Id = Idx;
(*Knot)->Flags = 0;
if (Read_Line(Stream, Line)) goto Eof; /* Spline parm 1 */
sscanf(Line, "%lf %lf %lf",&Alfa1, &Gamma1, &Magnitude1);
if (Read_Line(Stream, Line)) goto Eof; /* Spline parm 2 */
sscanf(Line, "%lf %lf %lf",&Alfa2, &Gamma2, &Magnitude2);
if (i1 & 1) Tension = 0.0; /* "Smooth" */
else Tension = 1.0; /* "Peak" */
Bias = 0.0;
Continuity = 0.0;
(*Knot)->Tension = Tension;
(*Knot)->Bias = Bias;
(*Knot)->Continuity = Continuity;
return(FALSE);
Eof:
Display_Message("Eof before expected");
fclose(Stream);
return(TRUE);
} /* JMan_Knot_Read */
Boolean_T JMan_File_Read(char *Filename)
/************************************************************************/
/* */
/* */
/************************************************************************/
{
FILE *Stream;
char Line[Buffer_Length+1];
Spline_T *Spline;
Knot_T *Knot;
int Spline_Id;
int Knot_Id;
int Point_Id;
int Nbr_Points;
int Nbr_Splines;
int Nbr_Knots;
int i;
short Point_Table[Size_JMan_Point_Table];
Display_Status("Loading Journeyman object...");
Set_Pointer(TRUE);
for (i = 0; i < Size_JMan_Point_Table; i++) Point_Table[i] = 0;
JMan_Point_Table_Idx = 0;
JMan_Point_Table = Point_Table;
Nbr_Points = 0;
Spline = NULL;
Splines_Init();
Stream = fopen(Filename, "r");
if (Stream == NULL) {
Display_Open_Error_Msg(Filename);
Set_Pointer(FALSE);
return(TRUE);
} /* if */
if (JMan_Header_Read(Stream, &Nbr_Splines)) {
Set_Pointer(FALSE);
fclose(Stream);
return(TRUE);
} /* if */
for (Spline_Id = 0; Spline_Id < Nbr_Splines; Spline_Id++) {
Spline = Spline_New();
if (Spline == NULL) {
Display_Message("Couldn't allocate memory for new spline");
Set_Pointer(FALSE);
fclose(Stream);
Splines_Init();
return(TRUE);
}
Spline->Flags = 0;
Spline->Nbr_Knots = 0;
/* Spline->Loop = FALSE; */
if (Read_Line(Stream, Line)) goto Eof;
Nbr_Knots = atoi(Line);
if (Nbr_Knots < 1) {
sprintf(Error_Msg, "Nbr of knots (%s) out of range", Line);
Display_Message(Error_Msg);
Set_Pointer(FALSE);
fclose(Stream);
Splines_Init();
return(TRUE);
} /* if */
Knot = NULL;
for (Knot_Id = 0; Knot_Id < Nbr_Knots; Knot_Id++) {
sprintf(Error_Msg, "Reading spline %d", Spline_Id);
Display_Status(Error_Msg);
if (JMan_Knot_Read(Stream, Spline, &Knot, &Nbr_Points)) {
fclose(Stream);
Splines_Init();
Set_Pointer(FALSE);
return(TRUE);
} /* if */
} /* for */
Spline->Nbr_Knots = Nbr_Knots;
} /* for */
fclose(Stream);
/****************************************************************/
/* */
/* Now postprocess the data. */
/* Right now the knots points to the JMan_Point_Table, and not */
/* to the points, furthermore point reference-counts are wrong */
/* So do the following: */
/* */
/* For each knot: */
/* */
/* Get idx into Jman point table. */
/* get idx to point from JMan point table. */
/* If this idx < 0, then this is itself a reference to the */
/* point table, so fetch this idx from the table. */
/* Continue with this while the idx is < 0. */
/* Now set real point_id in the knot and update the reference*/
/* count. */
/* */
/****************************************************************/
Display_Status("Post Processing data");
for (Spline = Splines; Spline != NULL; Spline = Spline->Next) {
for (Knot_Id = 0, Knot = Spline->First;
Knot_Id < Spline->Nbr_Knots; Knot_Id++, Knot = Knot->Next) {
/* Get idx into JMan point table */
i = Knot->Point_Id;
if (i < 1 || i >= Size_JMan_Point_Table) {
sprintf(Error_Msg, "Unused index (%d) in point table", i);
Display_Message(Error_Msg);
Splines_Init();
Set_Pointer(FALSE);
return(TRUE);
} /* if */
while ( (Point_Id = JMan_Point_Table[i]) < 0) {
i = -Point_Id;
if (i < 1 || i >= Size_JMan_Point_Table) {
sprintf(Error_Msg, "Unused index (%d) in point table", i);
Display_Message(Error_Msg);
Splines_Init();
Set_Pointer(FALSE);
return(TRUE);
} /* if */
} /* while */
if (Point_Id < 0 || Point_Id > Max_Nbr_Points) {
sprintf(Error_Msg, "Bad reference (%d) in point table %d", Point_Id, i);
Display_Message(Error_Msg);
Splines_Init();
Set_Pointer(FALSE);
return(TRUE);
} /* if */
Points[Point_Id].Reference_Count++;
Knot->Point_Id = Point_Id;
} /* for */
} /* for */
Display_Status(NULL);
Set_Pointer(FALSE);
return(FALSE);
Eof:
Display_Status(NULL);
Display_Message("Eof before expected");
fclose(Stream);
Splines_Init();
Set_Pointer(FALSE);
return(TRUE);
} /* JMan_File_Read */
Boolean_T Config_File_Write(char *Filename)
/************************************************************************/
/* */
/* Write the config file with the name 'Filename'. */
/* */
/* Return TRUE in case of error. */
/* */
/************************************************************************/
{
FILE *Stream;
char Line[Buffer_Length+1];
double D1, D2, D3;
Stream = fopen(Filename, "w");
if (Stream == NULL) {
Display_Open_Error_Msg(Filename);
return(TRUE);
}
D1 = Delay_Draw_Seconds;
D2 = Delay_Draw_Micros;
D3 = D1 + D2 / 1000000.0;
fprintf(Stream, "#\n");
fprintf(Stream, "#Configuration file for ICoons version 1.0\n");
fprintf(Stream, "#\n");
fprintf(Stream, "Delay_Draw = %lf\n", D3);
fprintf(Stream, "Spline_Resolution = %d\n", Spline_Resolution);
fprintf(Stream, "Patch_Resolution = %d\n", Patch_Resolution);
fprintf(Stream, "Backface_Culling = %d\n", Backface_Culling ? 'Y' : 'N');
fprintf(Stream, "Grid_Size = %lf\n", Grid_Size);
fprintf(Stream, "Grid_Active = %c\n", Grid_Active ? 'Y' : 'N');
fprintf(Stream, "Grid_Snap_Active = %c\n", Grid_Snap_Active ? 'Y' : 'N');
fprintf(Stream, "MQ_Size_KnotInfo = %d\n", MQ_Size_KnotInfo);
fprintf(Stream, "MQ_Size_Rotate_P = %d\n", MQ_Size_Rotate_P);
fprintf(Stream, "MQ_Size_Rotate_G = %d\n", MQ_Size_Rotate_G);
fprintf(Stream, "MQ_Size_Scale_G = %d\n", MQ_Size_Scale_G);
fprintf(Stream, "MQ_Size_Move_G = %d\n", MQ_Size_Move_G);
fprintf(Stream, "MQ_Size_Move = %d\n", MQ_Size_Move);
fclose(Stream);
return(FALSE);
} /* Config_File_Write */
Boolean_T Config_File_Read(char *Filename)
/************************************************************************/
/* */
/* Read the config file with the name 'Filename'. */
/* */
/* Return TRUE in case of error. */
/* */
/************************************************************************/
{
FILE *Stream;
char Line[Buffer_Length+1];
char *Name, *Value;
double D1, D2, D3;
long L;
Stream = fopen(Filename, "r");
if (Stream == NULL) {
sprintf(Line, "s:%s", Filename);
Stream = fopen(Line, "r");
if (Stream == NULL) {
Display_Open_Error_Msg(Filename);
return(TRUE);
}
} /* if */
while (! Read_Line(Stream, Line)) {
Name = strtok(Line, "=");
if (Name == NULL) continue;
Value = strtok(NULL, "\n");
if (Value == NULL) continue;
StrTrim(Name, Name);
if (strcmp(Name, "Delay_Draw") == 0) {
D1 = atof(Value);
if (D1 <= 0.0) continue;
D3 = modf(D1, &D2);
Delay_Draw_Seconds = D2;
Delay_Draw_Micros = D3 * 1000000.0;
} else if (strcmp(Name, "Spline_Resolution") == 0) {
L = atoi(Value);
if (L > 0 && L <= Max_Spline_Resolution) Spline_Resolution = L;
} else if (strcmp(Name, "Patch_Resolution") == 0) {
L = atoi(Value);
if (L > 0 && L <= Max_Patch_Resolution) Patch_Resolution = L;
} else if (strcmp(Name, "Backface_Culling") == 0) {
StrTrim(Value, Value);
Backface_Culling = (*Value == 'y' || *Value == 'Y');
} else if (strcmp(Name, "Grid_Size") == 0) {
D1 = atof(Value);
if (D1 > 0.5 && D1 < 500.0) Grid_Size = D1;
} else if (strcmp(Name, "Grid_Active") == 0) {
StrTrim(Value, Value);
Grid_Active = (*Value == 'y' || *Value == 'Y');
} else if (strcmp(Name, "Grid_Snap_Active") == 0) {
StrTrim(Value, Value);
Grid_Snap_Active = (*Value == 'y' || *Value == 'Y');
} else if (strcmp(Value, "MQ_Size_KnotInfo") == 0) {
L = atoi(Value);
if (L >= 0 && L <= 5) MQ_Size_KnotInfo = L;
} else if (strcmp(Value, "MQ_Size_Rotate_P") == 0) {
L = atoi(Value);
if (L >= 0 && L <= 5) MQ_Size_Rotate_P = L;
} else if (strcmp(Value, "MQ_Size_Rotate_G") == 0) {
L = atoi(Value);
if (L >= 0 && L <= 5) MQ_Size_Rotate_G = L;
} else if (strcmp(Value, "MQ_Size_Scale_G") == 0) {
L = atoi(Value);
if (L >= 0 && L <= 5) MQ_Size_Scale_G = L;
} else if (strcmp(Value, "MQ_Size_Move_G") == 0) {
L = atoi(Value);
if (L >= 0 && L <= 5) MQ_Size_Move_G = L;
} else if (strcmp(Value, "MQ_Size_Move") == 0) {
L = atoi(Value);
if (L >= 0 && L <= 5) MQ_Size_Move = L;
} /* if .. else .. else .. */
} /* while */
fclose(Stream);
return(FALSE);
} /* Config_File_Read */