]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/gtkgensurf/gensurf.cpp
transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / contrib / gtkgensurf / gensurf.cpp
1 /*\r
2 GenSurf plugin for GtkRadiant\r
3 Copyright (C) 2001 David Hyde, Loki software and qeradiant.com\r
4 \r
5 This library is free software; you can redistribute it and/or\r
6 modify it under the terms of the GNU Lesser General Public\r
7 License as published by the Free Software Foundation; either\r
8 version 2.1 of the License, or (at your option) any later version.\r
9 \r
10 This library is distributed in the hope that it will be useful,\r
11 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
13 Lesser General Public License for more details.\r
14 \r
15 You should have received a copy of the GNU Lesser General Public\r
16 License along with this library; if not, write to the Free Software\r
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
18 */\r
19 \r
20 #include <gtk/gtk.h>\r
21 #include <stdio.h>\r
22 #include <stdlib.h>\r
23 /*\r
24 #include <string.h>\r
25 #include <tchar.h>\r
26 #include <math.h>\r
27 */\r
28 #include "gensurf.h"\r
29 \r
30 char      gszAppDir[NAME_MAX];\r
31 char      gszCaption[64];\r
32 char      gszIni[NAME_MAX];\r
33 char      gszHelpFile[NAME_MAX];\r
34 char      gszMapFile[NAME_MAX];\r
35 char      gszVersion[64];\r
36 double    Amplitude;\r
37 double    Roughness;\r
38 double    TexOffset[2];\r
39 double    TexScale[2];\r
40 double    WaveLength;\r
41 double    Hll, Hur, Vll, Vur;\r
42 double    Z00, Z01, Z10, Z11;\r
43 ELEMENT   Vertex[(MAX_ROWS+1)*(MAX_ROWS+1)];\r
44 int       AddHints;\r
45 int       ArghRad2;\r
46 int       AutoOverwrite;\r
47 int       Decimate=0;\r
48 int                             SnapToGrid=0; // 0, or the grid size to snap to. // Hydra : snap to grid\r
49 int       FileAppend=0;\r
50 int       FixBorders;\r
51 int       HideBackFaces=0;\r
52 int       NH, NV;\r
53 int       NumVerticesSelected;\r
54 int       Plane;\r
55 int       Preview;\r
56 int       RandomSeed=1;\r
57 int       Skybox;\r
58 int       UseDetail;\r
59 int       UseLadder;\r
60 int       VertexMode=0;\r
61 int       WaveType;\r
62 int       gNumNodes=0;\r
63 int       gNumTris=0;\r
64 int       vid_x, vid_y;\r
65 int       view_x, view_y;\r
66 int       view_cx, view_cy;\r
67 int       UsePatches;\r
68 int       SlantAngle;\r
69 int       GimpHints;\r
70 int                             Antialiasing; // ^Fishman - Antializing for the preview window.\r
71 int                             AddTerrainKey; // ^Fishman - Add terrain key to func_group.\r
72 int                             SP; // ^Fishman - Snap to grid.\r
73 \r
74 GtkWidget *g_pWnd;        // ghwnd;\r
75 GtkWidget *g_pRadiantWnd; // ghwnd_main;\r
76 /*HWND      ghwndAngles;\r
77 */GtkWidget *g_pWndPreview;\r
78 GtkWidget *g_pPreviewWidget;\r
79 MYBITMAP  gbmp;\r
80 NODE      *gNode=(NODE *)NULL;\r
81 TRI       *gTri=(TRI *)NULL;\r
82 \r
83 int       Game;\r
84 bounding_box PlayerBox[NUMGAMES] = { {{-16., 16.}, {-16., 16.}, {-24., 32.}},    // Quake2\r
85                                      {{-16., 16.}, {-16., 16.}, {-36., 36.}},    // Half-Life\r
86                                      {{-16., 16.}, {-16., 16.}, {-32., 32.}},    // SiN\r
87                                      {{-16., 16.}, {-16., 16.}, {-24., 32.}},    // Heretic2 (guess)\r
88                                      {{-16., 16.}, {-16., 16.}, {-24., 32.}},    // KingPin (guess)\r
89                                      {{-30., 30.}, {-30., 30.}, {-10.,160.}},    // Genesis3D (no idea)\r
90                                      {{-16., 16.}, {-16., 16.}, {-24., 32.}}};   // Quake3 (not sure)\r
91 //char      gszOutputDir[NUMGAMES][NAME_MAX];\r
92 //char      gszTextureDir[NUMGAMES][NAME_MAX];\r
93 char      Texture[NUMGAMES][3][64];\r
94 //char      pakfile[NUMGAMES][NAME_MAX];\r
95 //char      lastpakfile[NUMGAMES][NAME_MAX];\r
96 //int       UsePak[NUMGAMES];\r
97 //char      GameDir[NUMGAMES][NAME_MAX];\r
98 \r
99 char GameName[NUMGAMES][16] = {"Quake2", "Half-Life", "SiN", "Heretic2", "Kingpin", "Genesis3D", "Quake3" };\r
100 \r
101 \r
102 bool GenSurfInit ()\r
103 {\r
104   strcpy (gszVersion, "1.05");\r
105   strcpy (gszCaption, "GtkGenSurf");\r
106   if (strlen (gszVersion))\r
107   {\r
108     strcat (gszCaption, " v");\r
109     strcat (gszCaption, gszVersion);\r
110   }\r
111 \r
112   strcpy (gszIni, g_FuncTable.m_pfnProfileGetDirectory ());\r
113   strcat (gszIni, "gensurf.ini");\r
114 \r
115 /*if (g_FuncTable.m_pfnReadProjectKey != NULL)\r
116   {\r
117     char *basepath;\r
118 \r
119     basepath = g_FuncTable.m_pfnReadProjectKey("basepath");\r
120     if (basepath)\r
121     {\r
122       g_strdown (basepath);\r
123       if (strstr(basepath,"baseq3"))\r
124         Game = QUAKE3;\r
125       else if (strstr (basepath,"baseq2"))\r
126         Game = QUAKE2;\r
127       else // Gotta have a game, might as well be Quake3\r
128         Game = QUAKE3;\r
129     }\r
130     else\r
131       Game = QUAKE3;\r
132   }\r
133   else */\r
134     Game = QUAKE3;\r
135 \r
136   ReadIniFile (gszIni);\r
137 \r
138   if (g_pWnd == NULL)\r
139     g_pWnd = create_main_dialog ();\r
140 \r
141   return true;\r
142 }\r
143 \r
144 // Reads default values\r
145 \r
146 #define OPTS_SECTION "Options"\r
147 \r
148 void ReadIniFile (const char *file)\r
149 {\r
150   char *Text;\r
151   float x1,x2,x3,x4;\r
152   int   i;\r
153 \r
154   Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "Amplitude", "");\r
155   if (strlen (Text))\r
156     Amplitude = atof (Text);\r
157   else\r
158     Amplitude = 128;\r
159 \r
160   Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "Roughness", "");\r
161   if (strlen (Text))\r
162     Roughness = atof (Text);\r
163   else\r
164     Roughness = 16;\r
165 \r
166   Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "WaveLength", "");\r
167   if (strlen (Text))\r
168     WaveLength = atof (Text);\r
169   else\r
170     WaveLength = 1024;\r
171 \r
172   Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "Extents", "");\r
173   if (strlen (Text))\r
174   {\r
175     sscanf(Text,"%f,%f,%f,%f",&x1,&x2,&x3,&x4);\r
176     Hll = x1;\r
177     Vll = x2;\r
178     Hur = x3;\r
179     Vur = x4;\r
180   }\r
181   else\r
182   {\r
183     Hll = -512;\r
184     Vll = -512;\r
185     Hur =  512;\r
186     Vur =  512;\r
187   }\r
188 \r
189   Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "CornerValues", "");\r
190   if (strlen (Text))\r
191   {\r
192     sscanf(Text,"%f,%f,%f,%f",&x1,&x2,&x3,&x4);\r
193     Z00 = x1;\r
194     Z01 = x2;\r
195     Z10 = x3;\r
196     Z11 = x4;\r
197   }\r
198   else\r
199   {\r
200     Z00 = 0.;\r
201     Z01 = 0.;\r
202     Z10 = 0.;\r
203     Z11 = 0.;\r
204   }\r
205 \r
206   Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "TextureOffset", "");\r
207   if (strlen (Text))\r
208   {\r
209     sscanf(Text,"%f,%f",&x1,&x2);\r
210     TexOffset[0] = x1;\r
211     TexOffset[1] = x2;\r
212   }\r
213   else\r
214   {\r
215     TexOffset[0] = 0.;\r
216     TexOffset[1] = 0.;\r
217   }\r
218 \r
219   Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION,"TextureScale","");\r
220   if (strlen (Text))\r
221   {\r
222     sscanf(Text,"%f,%f",&x1,&x2);\r
223     TexScale[0] = x1;\r
224     TexScale[1] = x2;\r
225     if(TexScale[0] == 0.) TexScale[0] = 1.0;\r
226     if(TexScale[1] == 0.) TexScale[1] = 1.0;\r
227   }\r
228   else\r
229   {\r
230     TexScale[0] = 1.;\r
231     TexScale[1] = 1.;\r
232   }\r
233 \r
234   NH = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"NH",8);\r
235   NH = max(1,min(NH,MAX_ROWS));\r
236   NV = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"NV",8);\r
237   NV = max(1,min(NV,MAX_ROWS));\r
238 \r
239 //      Decimate   = GetPrivateProfileInt(OPTS_SECTION,"Decimate",0,file);\r
240 //      Decimate = max(0,min(Decimate,100));\r
241 \r
242   AddHints                      = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"AddHints",0);\r
243   ArghRad2                      = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"ArghRad2",0);\r
244   AutoOverwrite = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"AutoOverwrite",0);\r
245   FixBorders            = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"FixBorders",1);\r
246   HideBackFaces = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"HideBackFaces",0);\r
247   Plane                                 = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"Plane",0);\r
248   Preview                               = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"Preview", 0);\r
249         Antialiasing    = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"Antialiasing",0); // ^Fishman - Antializing for the preview window.\r
250   RandomSeed            = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"RandomSeed",1);\r
251   Skybox                                = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"Skybox",0);\r
252   UseDetail                     = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"UseDetail",0);\r
253         AddTerrainKey   =       g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"AddTerrainKey",0); // ^Fishman - Add terrain key to func_group.\r
254   UseLadder                     = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"UseLadder",0);\r
255   WaveType                      = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"WaveType",0);\r
256   vid_x                                 = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"vid_x", 0);\r
257   vid_y                                 = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"vid_y", 0);\r
258   view_x                                = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"view_x",0);\r
259   view_y                                = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"view_y",0);\r
260   view_cx                               = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"view_cx",0);\r
261   view_cy                               = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"view_cy",0);\r
262 \r
263   UsePatches            = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"UsePatches",0);\r
264 \r
265   SlantAngle = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"SlantAngle",60);\r
266   GimpHints  = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"GimpHints",0);\r
267 \r
268   for(i=0; i<NUMGAMES; i++)\r
269   {\r
270     //    strcpy (gszOutputDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"OutputDir",""));\r
271     strcpy (Texture[i][0], g_FuncTable.m_pfnProfileLoadString (file, GameName[i], "Texture", ""));\r
272     strcpy (Texture[i][1], g_FuncTable.m_pfnProfileLoadString (file, GameName[i], "Texture2", ""));\r
273     strcpy (Texture[i][2], g_FuncTable.m_pfnProfileLoadString (file, GameName[i], "Texture3", ""));\r
274     //    strcpy (gszTextureDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"TextureDir",""));\r
275     //    UsePak[i] = GetPrivateProfileInt(GameName[i],"UsePak",0);\r
276     //    strcpy (pakfile[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"PakFile",""));\r
277     //    strcpy (lastpakfile[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"LastPakFile",""));\r
278     //    strcpy (GameDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"GameDir","\0"));\r
279   }\r
280   /*\r
281         if(!strlen(gszTextureDir[QUAKE2]))\r
282                 strcpy(gszTextureDir[QUAKE2],"c:\\quake2\\baseq2\\textures\\");\r
283         if(!strlen(gszTextureDir[KINGPIN]))\r
284                 strcpy(gszTextureDir[KINGPIN],"c:\\kingpin\\main\\textures\\");\r
285   */\r
286   if(!strlen(Texture[QUAKE2][0]))    strcpy(Texture[QUAKE2][0],   "textures/e1u1/grass1_4");\r
287   if(!strlen(Texture[HALFLIFE][0]))  strcpy(Texture[HALFLIFE][0], "textures/OUT_GRND1");\r
288   if(!strlen(Texture[SIN][0]))       strcpy(Texture[SIN][0],      "textures/generic/floor_organic/fl_grass");\r
289   if(!strlen(Texture[HERETIC2][0]))  strcpy(Texture[HERETIC2][0], "textures/canyon/canyon05");\r
290   if(!strlen(Texture[KINGPIN][0]))   strcpy(Texture[KINGPIN][0],  "textures/bricks/s_sr_m3");\r
291   if(!strlen(Texture[GENESIS3D][0])) strcpy(Texture[GENESIS3D][0],"textures/rock13");\r
292   if(!strlen(Texture[QUAKE3][0]))    strcpy(Texture[QUAKE3][0],   "textures/organics/grass3");\r
293   if(!strlen(Texture[QUAKE3][1]))    strcpy(Texture[QUAKE3][1],   "textures/common/caulk");\r
294 \r
295   strcpy (gbmp.name, g_FuncTable.m_pfnProfileLoadString (file, "Bitmap","Filename",""));\r
296 \r
297   if (strlen(gbmp.name))\r
298     OpenBitmap ();\r
299 \r
300   strcpy (gbmp.defpath, g_FuncTable.m_pfnProfileLoadString (file, "Bitmap","DefaultPath",""));\r
301 \r
302   Text = g_FuncTable.m_pfnProfileLoadString (file, "Bitmap","BlackValue","");\r
303   if (strlen (Text))\r
304     gbmp.black_value = atof (Text);\r
305   else\r
306     gbmp.black_value = 0;\r
307 \r
308   Text = g_FuncTable.m_pfnProfileLoadString (file, "Bitmap","WhiteValue","");\r
309   if (strlen (Text))\r
310     gbmp.white_value = atof (Text);\r
311   else\r
312     gbmp.white_value = 256.;\r
313 }\r
314 \r
315 /*\r
316 ============\r
317 va\r
318 \r
319 does a varargs printf into a temp buffer, so I don't need to have\r
320 varargs versions of all text functions.\r
321 FIXME: make this buffer size safe someday\r
322 ============\r
323 */\r
324 char *va (char *format, ...)\r
325 {\r
326   va_list argptr;\r
327   static char string[1024];\r
328 \r
329   va_start (argptr, format);\r
330   vsprintf (string, format,argptr);\r
331   va_end (argptr);\r
332 \r
333   return string;        \r
334 }\r
335 \r
336 \r
337 // Writes current values to INI file\r
338 void WriteIniFile(const char *file)\r
339 {\r
340   int i;\r
341 \r
342   g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "Amplitude",    va("%g",Amplitude));\r
343   g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "Roughness",    va("%g",Roughness));\r
344   g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "WaveLength",   va("%g",WaveLength));\r
345   g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "Extents",      va("%g,%g,%g,%g",Hll,Vll,Hur,Vur));\r
346   g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "CornerValues", va("%g,%g,%g,%g",Z00,Z01,Z10,Z11));\r
347   g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "TextureOffset",va("%g,%g",TexOffset[0],TexOffset[1]));\r
348   g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "TextureScale", va("%g,%g",TexScale[0],TexScale[1]));\r
349   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "NH", NH);\r
350   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "NV", NV);\r
351   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "AddHints", AddHints);\r
352   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "ArghRad2", ArghRad2);\r
353   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "AutoOverwrite", AutoOverwrite);\r
354   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "FixBorders", FixBorders);\r
355   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "Plane", Plane);\r
356   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "Preview", Preview);\r
357         g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "Antialiasing", Antialiasing); // ^Fishman - Antializing for the preview window.\r
358   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "RandomSeed", RandomSeed);\r
359   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "Skybox", Skybox);\r
360   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "UseDetail", UseDetail);\r
361   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "AddTerrainKey", AddTerrainKey); // ^Fishman - Add terrain key to func_group.\r
362   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "UseLadder", UseLadder);\r
363   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "WaveType", WaveType);\r
364   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "vid_x", vid_x);\r
365   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "vid_y", vid_y);\r
366   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "view_x", view_x);\r
367   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "view_y", view_y);\r
368   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "view_cx", view_cx);\r
369   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "view_cy", view_cy);\r
370   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "UsePatches", UsePatches);\r
371   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "SlantAngle", SlantAngle);\r
372   for(i=0; i<NUMGAMES; i++)\r
373   {\r
374     g_FuncTable.m_pfnProfileSaveString (file, GameName[i], "Texture",   Texture[i][0] );\r
375     g_FuncTable.m_pfnProfileSaveString (file, GameName[i], "Texture2",  Texture[i][1] );\r
376     g_FuncTable.m_pfnProfileSaveString (file, GameName[i], "Texture3",  Texture[i][2] );\r
377   }\r
378 \r
379   g_FuncTable.m_pfnProfileSaveString (file, "Bitmap", "Filename", gbmp.name );\r
380   g_FuncTable.m_pfnProfileSaveString (file, "Bitmap", "DefaultPath", gbmp.defpath );\r
381   g_FuncTable.m_pfnProfileSaveString (file, "Bitmap", "BlackValue", va("%g",gbmp.black_value));\r
382   g_FuncTable.m_pfnProfileSaveString (file, "Bitmap", "WhiteValue", va("%g",gbmp.white_value));\r
383 //g_FuncTable.m_pfnProfileSaveString (file, "Formula", "Formula", ExcelFunc );\r
384 }\r
385 \r
386 void UpdatePreview (bool DataChange)\r
387 {\r
388   if (g_pWndPreview && GTK_WIDGET_VISIBLE (g_pWndPreview))\r
389   {\r
390     if (DataChange)\r
391       GenerateXYZ ();\r
392 \r
393     gtk_widget_draw (g_pPreviewWidget, NULL);\r
394   }\r
395 }\r
396 \r
397 void SaveSetup (GtkWidget *parent)\r
398 {\r
399   const char *name = g_FuncTable.m_pfnFileDialog (parent, false, "Save GenSurf Settings",\r
400                                              g_FuncTable.m_pfnProfileGetDirectory ());\r
401 \r
402   if (name != NULL)\r
403   {\r
404     char key[32], text[32]; \r
405     int i, j;\r
406 \r
407     WriteIniFile (name);\r
408     g_FuncTable.m_pfnProfileSaveString (name, OPTS_SECTION,"MapFile",gszMapFile);\r
409     sprintf(text,"0x%04x",FileAppend);\r
410     g_FuncTable.m_pfnProfileSaveString (name, OPTS_SECTION,"Append",text);\r
411     sprintf(text,"0x%04x",Decimate);\r
412     g_FuncTable.m_pfnProfileSaveString (name, OPTS_SECTION,"Decimate",text);\r
413     for(i=0; i<=NH; i++)\r
414     {\r
415       for(j=0; j<=NV; j++)\r
416       {\r
417         if(xyz[i][j].fixed)\r
418         {\r
419           sprintf(key,"I%dJ%d",i,j);\r
420           sprintf(text,"%g %g %g", xyz[i][j].fixed_value, xyz[i][j].range, xyz[i][j].rate);\r
421           g_FuncTable.m_pfnProfileSaveString (name, "FixedPoints",key,text);\r
422         }\r
423       }\r
424     }\r
425   }\r
426 }\r
427 \r
428 void OpenSetup (GtkWidget *parent, int UseDefaults)\r
429 {\r
430   const char *name;\r
431   char key[32], *text;\r
432   float value,range,rate;\r
433   int i, j;\r
434 \r
435   if (UseDefaults)\r
436     name = g_strdup ("plugins/defaults.srf"); // dummy string\r
437   else\r
438     name = g_FuncTable.m_pfnFileDialog (parent, true, "Open GenSurf Settings",\r
439                                         g_FuncTable.m_pfnProfileGetDirectory ());\r
440 \r
441   if(name != NULL)\r
442   {\r
443     ReadIniFile (name);\r
444     Decimate   = g_FuncTable.m_pfnProfileLoadInt (name, OPTS_SECTION,"Decimate",0);\r
445     Decimate   = max(0,min(Decimate,100));\r
446 \r
447     for (i=0; i<=NH; i++)\r
448     {\r
449       for (j=0; j<=NV; j++)\r
450       {\r
451         sprintf(key,"I%dJ%d",i,j);\r
452         text = g_FuncTable.m_pfnProfileLoadString (name, "FixedPoints", key, "");\r
453         if (strlen (text))\r
454         {\r
455           xyz[i][j].fixed = 1;\r
456           xyz[i][j].rate        = 0.;\r
457           sscanf(text,"%g %g %g",&value,&range,&rate);\r
458           xyz[i][j].fixed_value = value;\r
459           xyz[i][j].range       = range;\r
460           xyz[i][j].rate        = rate;\r
461         }\r
462         else\r
463           xyz[i][j].fixed = 0;\r
464       }\r
465     }\r
466   }\r
467 }\r