]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - contrib/gtkgensurf/gensurf.cpp
more eol-style
[xonotic/netradiant.git] / contrib / gtkgensurf / gensurf.cpp
index b9ff7d470764783f888d0f979faa64543d1188a2..32b54b5578519e41452325207671bee5a9b4c50f 100644 (file)
-/*\r
-GenSurf plugin for GtkRadiant\r
-Copyright (C) 2001 David Hyde, Loki software and qeradiant.com\r
-\r
-This library is free software; you can redistribute it and/or\r
-modify it under the terms of the GNU Lesser General Public\r
-License as published by the Free Software Foundation; either\r
-version 2.1 of the License, or (at your option) any later version.\r
-\r
-This library is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
-Lesser General Public License for more details.\r
-\r
-You should have received a copy of the GNU Lesser General Public\r
-License along with this library; if not, write to the Free Software\r
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
-*/\r
-\r
-#include <gtk/gtk.h>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-/*\r
-#include <string.h>\r
-#include <tchar.h>\r
-#include <math.h>\r
-*/\r
-#include "gensurf.h"\r
-\r
-char      gszAppDir[NAME_MAX];\r
-char      gszCaption[64];\r
-char      gszIni[NAME_MAX];\r
-char      gszHelpFile[NAME_MAX];\r
-char      gszMapFile[NAME_MAX];\r
-char      gszVersion[64];\r
-double    Amplitude;\r
-double    Roughness;\r
-double    TexOffset[2];\r
-double    TexScale[2];\r
-double    WaveLength;\r
-double    Hll, Hur, Vll, Vur;\r
-double    Z00, Z01, Z10, Z11;\r
-ELEMENT   Vertex[(MAX_ROWS+1)*(MAX_ROWS+1)];\r
-int       AddHints;\r
-int       ArghRad2;\r
-int       AutoOverwrite;\r
-int       Decimate=0;\r
-int                            SnapToGrid=0; // 0, or the grid size to snap to. // Hydra : snap to grid\r
-int       FileAppend=0;\r
-int       FixBorders;\r
-int       HideBackFaces=0;\r
-int       NH, NV;\r
-int       NumVerticesSelected;\r
-int       Plane;\r
-int       Preview;\r
-int       RandomSeed=1;\r
-int       Skybox;\r
-int       UseDetail;\r
-int       UseLadder;\r
-int       VertexMode=0;\r
-int       WaveType;\r
-int       gNumNodes=0;\r
-int       gNumTris=0;\r
-int       vid_x, vid_y;\r
-int       view_x, view_y;\r
-int       view_cx, view_cy;\r
-int       UsePatches;\r
-int       SlantAngle;\r
-int       GimpHints;\r
-int                            Antialiasing; // ^Fishman - Antializing for the preview window.\r
-int                            AddTerrainKey; // ^Fishman - Add terrain key to func_group.\r
-int                            SP; // ^Fishman - Snap to grid.\r
-\r
-GtkWidget *g_pWnd;        // ghwnd;\r
-GtkWidget *g_pRadiantWnd; // ghwnd_main;\r
-/*HWND      ghwndAngles;\r
-*/GtkWidget *g_pWndPreview;\r
-GtkWidget *g_pPreviewWidget;\r
-MYBITMAP  gbmp;\r
-NODE      *gNode=(NODE *)NULL;\r
-TRI       *gTri=(TRI *)NULL;\r
-\r
-int       Game;\r
-bounding_box PlayerBox[NUMGAMES] = { {{-16., 16.}, {-16., 16.}, {-24., 32.}},    // Quake2\r
-                                     {{-16., 16.}, {-16., 16.}, {-36., 36.}},    // Half-Life\r
-                                     {{-16., 16.}, {-16., 16.}, {-32., 32.}},    // SiN\r
-                                     {{-16., 16.}, {-16., 16.}, {-24., 32.}},    // Heretic2 (guess)\r
-                                     {{-16., 16.}, {-16., 16.}, {-24., 32.}},    // KingPin (guess)\r
-                                     {{-30., 30.}, {-30., 30.}, {-10.,160.}},   // Genesis3D (no idea)\r
-                                     {{-16., 16.}, {-16., 16.}, {-24., 32.}}};  // Quake3 (not sure)\r
-//char      gszOutputDir[NUMGAMES][NAME_MAX];\r
-//char      gszTextureDir[NUMGAMES][NAME_MAX];\r
-char      Texture[NUMGAMES][3][64];\r
-//char      pakfile[NUMGAMES][NAME_MAX];\r
-//char      lastpakfile[NUMGAMES][NAME_MAX];\r
-//int       UsePak[NUMGAMES];\r
-//char      GameDir[NUMGAMES][NAME_MAX];\r
-\r
-char GameName[NUMGAMES][16] = {"Quake2", "Half-Life", "SiN", "Heretic2", "Kingpin", "Genesis3D", "Quake3" };\r
-\r
-\r
-bool GenSurfInit ()\r
-{\r
-  strcpy (gszVersion, "1.05");\r
-  strcpy (gszCaption, "GtkGenSurf");\r
-  if (strlen (gszVersion))\r
-  {\r
-    strcat (gszCaption, " v");\r
-    strcat (gszCaption, gszVersion);\r
-  }\r
-\r
-  strcpy (gszIni, g_FuncTable.m_pfnProfileGetDirectory ());\r
-  strcat (gszIni, "gensurf.ini");\r
-\r
-/*if (g_FuncTable.m_pfnReadProjectKey != NULL)\r
-  {\r
-    char *basepath;\r
-\r
-    basepath = g_FuncTable.m_pfnReadProjectKey("basepath");\r
-    if (basepath)\r
-    {\r
-      g_strdown (basepath);\r
-      if (strstr(basepath,"baseq3"))\r
-        Game = QUAKE3;\r
-      else if (strstr (basepath,"baseq2"))\r
-        Game = QUAKE2;\r
-      else // Gotta have a game, might as well be Quake3\r
-        Game = QUAKE3;\r
-    }\r
-    else\r
-      Game = QUAKE3;\r
-  }\r
-  else */\r
-    Game = QUAKE3;\r
-\r
-  ReadIniFile (gszIni);\r
-\r
-  if (g_pWnd == NULL)\r
-    g_pWnd = create_main_dialog ();\r
-\r
-  return true;\r
-}\r
-\r
-// Reads default values\r
-\r
-#define OPTS_SECTION "Options"\r
-\r
-void ReadIniFile (const char *file)\r
-{\r
-  char *Text;\r
-  float x1,x2,x3,x4;\r
-  int   i;\r
-\r
-  Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "Amplitude", "");\r
-  if (strlen (Text))\r
-    Amplitude = atof (Text);\r
-  else\r
-    Amplitude = 128;\r
-\r
-  Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "Roughness", "");\r
-  if (strlen (Text))\r
-    Roughness = atof (Text);\r
-  else\r
-    Roughness = 16;\r
-\r
-  Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "WaveLength", "");\r
-  if (strlen (Text))\r
-    WaveLength = atof (Text);\r
-  else\r
-    WaveLength = 1024;\r
-\r
-  Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "Extents", "");\r
-  if (strlen (Text))\r
-  {\r
-    sscanf(Text,"%f,%f,%f,%f",&x1,&x2,&x3,&x4);\r
-    Hll = x1;\r
-    Vll = x2;\r
-    Hur = x3;\r
-    Vur = x4;\r
-  }\r
-  else\r
-  {\r
-    Hll = -512;\r
-    Vll = -512;\r
-    Hur =  512;\r
-    Vur =  512;\r
-  }\r
-\r
-  Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "CornerValues", "");\r
-  if (strlen (Text))\r
-  {\r
-    sscanf(Text,"%f,%f,%f,%f",&x1,&x2,&x3,&x4);\r
-    Z00 = x1;\r
-    Z01 = x2;\r
-    Z10 = x3;\r
-    Z11 = x4;\r
-  }\r
-  else\r
-  {\r
-    Z00 = 0.;\r
-    Z01 = 0.;\r
-    Z10 = 0.;\r
-    Z11 = 0.;\r
-  }\r
-\r
-  Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "TextureOffset", "");\r
-  if (strlen (Text))\r
-  {\r
-    sscanf(Text,"%f,%f",&x1,&x2);\r
-    TexOffset[0] = x1;\r
-    TexOffset[1] = x2;\r
-  }\r
-  else\r
-  {\r
-    TexOffset[0] = 0.;\r
-    TexOffset[1] = 0.;\r
-  }\r
-\r
-  Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION,"TextureScale","");\r
-  if (strlen (Text))\r
-  {\r
-    sscanf(Text,"%f,%f",&x1,&x2);\r
-    TexScale[0] = x1;\r
-    TexScale[1] = x2;\r
-    if(TexScale[0] == 0.) TexScale[0] = 1.0;\r
-    if(TexScale[1] == 0.) TexScale[1] = 1.0;\r
-  }\r
-  else\r
-  {\r
-    TexScale[0] = 1.;\r
-    TexScale[1] = 1.;\r
-  }\r
-\r
-  NH = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"NH",8);\r
-  NH = max(1,min(NH,MAX_ROWS));\r
-  NV = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"NV",8);\r
-  NV = max(1,min(NV,MAX_ROWS));\r
-\r
-//     Decimate   = GetPrivateProfileInt(OPTS_SECTION,"Decimate",0,file);\r
-//     Decimate = max(0,min(Decimate,100));\r
-\r
-  AddHints                     = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"AddHints",0);\r
-  ArghRad2                     = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"ArghRad2",0);\r
-  AutoOverwrite        = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"AutoOverwrite",0);\r
-  FixBorders           = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"FixBorders",1);\r
-  HideBackFaces        = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"HideBackFaces",0);\r
-  Plane                                        = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"Plane",0);\r
-  Preview                              = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"Preview", 0);\r
-       Antialiasing    = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"Antialiasing",0); // ^Fishman - Antializing for the preview window.\r
-  RandomSeed           = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"RandomSeed",1);\r
-  Skybox                               = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"Skybox",0);\r
-  UseDetail                    = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"UseDetail",0);\r
-       AddTerrainKey   =       g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"AddTerrainKey",0); // ^Fishman - Add terrain key to func_group.\r
-  UseLadder                    = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"UseLadder",0);\r
-  WaveType                     = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"WaveType",0);\r
-  vid_x                                        = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"vid_x", 0);\r
-  vid_y                                        = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"vid_y", 0);\r
-  view_x                               = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"view_x",0);\r
-  view_y                               = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"view_y",0);\r
-  view_cx                              = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"view_cx",0);\r
-  view_cy                              = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"view_cy",0);\r
-\r
-  UsePatches           = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"UsePatches",0);\r
-\r
-  SlantAngle = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"SlantAngle",60);\r
-  GimpHints  = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"GimpHints",0);\r
-\r
-  for(i=0; i<NUMGAMES; i++)\r
-  {\r
-    //    strcpy (gszOutputDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"OutputDir",""));\r
-    strcpy (Texture[i][0], g_FuncTable.m_pfnProfileLoadString (file, GameName[i], "Texture", ""));\r
-    strcpy (Texture[i][1], g_FuncTable.m_pfnProfileLoadString (file, GameName[i], "Texture2", ""));\r
-    strcpy (Texture[i][2], g_FuncTable.m_pfnProfileLoadString (file, GameName[i], "Texture3", ""));\r
-    //    strcpy (gszTextureDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"TextureDir",""));\r
-    //    UsePak[i] = GetPrivateProfileInt(GameName[i],"UsePak",0);\r
-    //    strcpy (pakfile[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"PakFile",""));\r
-    //    strcpy (lastpakfile[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"LastPakFile",""));\r
-    //    strcpy (GameDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"GameDir","\0"));\r
-  }\r
-  /*\r
-       if(!strlen(gszTextureDir[QUAKE2]))\r
-               strcpy(gszTextureDir[QUAKE2],"c:\\quake2\\baseq2\\textures\\");\r
-       if(!strlen(gszTextureDir[KINGPIN]))\r
-               strcpy(gszTextureDir[KINGPIN],"c:\\kingpin\\main\\textures\\");\r
-  */\r
-  if(!strlen(Texture[QUAKE2][0]))    strcpy(Texture[QUAKE2][0],   "textures/e1u1/grass1_4");\r
-  if(!strlen(Texture[HALFLIFE][0]))  strcpy(Texture[HALFLIFE][0], "textures/OUT_GRND1");\r
-  if(!strlen(Texture[SIN][0]))       strcpy(Texture[SIN][0],      "textures/generic/floor_organic/fl_grass");\r
-  if(!strlen(Texture[HERETIC2][0]))  strcpy(Texture[HERETIC2][0], "textures/canyon/canyon05");\r
-  if(!strlen(Texture[KINGPIN][0]))   strcpy(Texture[KINGPIN][0],  "textures/bricks/s_sr_m3");\r
-  if(!strlen(Texture[GENESIS3D][0])) strcpy(Texture[GENESIS3D][0],"textures/rock13");\r
-  if(!strlen(Texture[QUAKE3][0]))    strcpy(Texture[QUAKE3][0],   "textures/organics/grass3");\r
-  if(!strlen(Texture[QUAKE3][1]))    strcpy(Texture[QUAKE3][1],   "textures/common/caulk");\r
-\r
-  strcpy (gbmp.name, g_FuncTable.m_pfnProfileLoadString (file, "Bitmap","Filename",""));\r
-\r
-  if (strlen(gbmp.name))\r
-    OpenBitmap ();\r
-\r
-  strcpy (gbmp.defpath, g_FuncTable.m_pfnProfileLoadString (file, "Bitmap","DefaultPath",""));\r
-\r
-  Text = g_FuncTable.m_pfnProfileLoadString (file, "Bitmap","BlackValue","");\r
-  if (strlen (Text))\r
-    gbmp.black_value = atof (Text);\r
-  else\r
-    gbmp.black_value = 0;\r
-\r
-  Text = g_FuncTable.m_pfnProfileLoadString (file, "Bitmap","WhiteValue","");\r
-  if (strlen (Text))\r
-    gbmp.white_value = atof (Text);\r
-  else\r
-    gbmp.white_value = 256.;\r
-}\r
-\r
-/*\r
-============\r
-va\r
-\r
-does a varargs printf into a temp buffer, so I don't need to have\r
-varargs versions of all text functions.\r
-FIXME: make this buffer size safe someday\r
-============\r
-*/\r
-char *va (char *format, ...)\r
-{\r
-  va_list argptr;\r
-  static char string[1024];\r
-\r
-  va_start (argptr, format);\r
-  vsprintf (string, format,argptr);\r
-  va_end (argptr);\r
-\r
-  return string;       \r
-}\r
-\r
-\r
-// Writes current values to INI file\r
-void WriteIniFile(const char *file)\r
-{\r
-  int i;\r
-\r
-  g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "Amplitude",    va("%g",Amplitude));\r
-  g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "Roughness",    va("%g",Roughness));\r
-  g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "WaveLength",   va("%g",WaveLength));\r
-  g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "Extents",      va("%g,%g,%g,%g",Hll,Vll,Hur,Vur));\r
-  g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "CornerValues", va("%g,%g,%g,%g",Z00,Z01,Z10,Z11));\r
-  g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "TextureOffset",va("%g,%g",TexOffset[0],TexOffset[1]));\r
-  g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "TextureScale", va("%g,%g",TexScale[0],TexScale[1]));\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "NH", NH);\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "NV", NV);\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "AddHints", AddHints);\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "ArghRad2", ArghRad2);\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "AutoOverwrite", AutoOverwrite);\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "FixBorders", FixBorders);\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "Plane", Plane);\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "Preview", Preview);\r
-       g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "Antialiasing", Antialiasing); // ^Fishman - Antializing for the preview window.\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "RandomSeed", RandomSeed);\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "Skybox", Skybox);\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "UseDetail", UseDetail);\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "AddTerrainKey", AddTerrainKey); // ^Fishman - Add terrain key to func_group.\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "UseLadder", UseLadder);\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "WaveType", WaveType);\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "vid_x", vid_x);\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "vid_y", vid_y);\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "view_x", view_x);\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "view_y", view_y);\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "view_cx", view_cx);\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "view_cy", view_cy);\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "UsePatches", UsePatches);\r
-  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "SlantAngle", SlantAngle);\r
-  for(i=0; i<NUMGAMES; i++)\r
-  {\r
-    g_FuncTable.m_pfnProfileSaveString (file, GameName[i], "Texture",   Texture[i][0] );\r
-    g_FuncTable.m_pfnProfileSaveString (file, GameName[i], "Texture2",  Texture[i][1] );\r
-    g_FuncTable.m_pfnProfileSaveString (file, GameName[i], "Texture3",  Texture[i][2] );\r
-  }\r
-\r
-  g_FuncTable.m_pfnProfileSaveString (file, "Bitmap", "Filename", gbmp.name );\r
-  g_FuncTable.m_pfnProfileSaveString (file, "Bitmap", "DefaultPath", gbmp.defpath );\r
-  g_FuncTable.m_pfnProfileSaveString (file, "Bitmap", "BlackValue", va("%g",gbmp.black_value));\r
-  g_FuncTable.m_pfnProfileSaveString (file, "Bitmap", "WhiteValue", va("%g",gbmp.white_value));\r
-//g_FuncTable.m_pfnProfileSaveString (file, "Formula", "Formula", ExcelFunc );\r
-}\r
-\r
-void UpdatePreview (bool DataChange)\r
-{\r
-  if (g_pWndPreview && GTK_WIDGET_VISIBLE (g_pWndPreview))\r
-  {\r
-    if (DataChange)\r
-      GenerateXYZ ();\r
-\r
-    gtk_widget_draw (g_pPreviewWidget, NULL);\r
-  }\r
-}\r
-\r
-void SaveSetup (GtkWidget *parent)\r
-{\r
-  const char *name = g_FuncTable.m_pfnFileDialog (parent, false, "Save GenSurf Settings",\r
-                                             g_FuncTable.m_pfnProfileGetDirectory ());\r
-\r
-  if (name != NULL)\r
-  {\r
-    char key[32], text[32]; \r
-    int i, j;\r
-\r
-    WriteIniFile (name);\r
-    g_FuncTable.m_pfnProfileSaveString (name, OPTS_SECTION,"MapFile",gszMapFile);\r
-    sprintf(text,"0x%04x",FileAppend);\r
-    g_FuncTable.m_pfnProfileSaveString (name, OPTS_SECTION,"Append",text);\r
-    sprintf(text,"0x%04x",Decimate);\r
-    g_FuncTable.m_pfnProfileSaveString (name, OPTS_SECTION,"Decimate",text);\r
-    for(i=0; i<=NH; i++)\r
-    {\r
-      for(j=0; j<=NV; j++)\r
-      {\r
-        if(xyz[i][j].fixed)\r
-        {\r
-          sprintf(key,"I%dJ%d",i,j);\r
-          sprintf(text,"%g %g %g", xyz[i][j].fixed_value, xyz[i][j].range, xyz[i][j].rate);\r
-          g_FuncTable.m_pfnProfileSaveString (name, "FixedPoints",key,text);\r
-        }\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-void OpenSetup (GtkWidget *parent, int UseDefaults)\r
-{\r
-  const char *name;\r
-  char key[32], *text;\r
-  float value,range,rate;\r
-  int i, j;\r
-\r
-  if (UseDefaults)\r
-    name = g_strdup ("plugins/defaults.srf"); // dummy string\r
-  else\r
-    name = g_FuncTable.m_pfnFileDialog (parent, true, "Open GenSurf Settings",\r
-                                        g_FuncTable.m_pfnProfileGetDirectory ());\r
-\r
-  if(name != NULL)\r
-  {\r
-    ReadIniFile (name);\r
-    Decimate   = g_FuncTable.m_pfnProfileLoadInt (name, OPTS_SECTION,"Decimate",0);\r
-    Decimate   = max(0,min(Decimate,100));\r
-\r
-    for (i=0; i<=NH; i++)\r
-    {\r
-      for (j=0; j<=NV; j++)\r
-      {\r
-        sprintf(key,"I%dJ%d",i,j);\r
-        text = g_FuncTable.m_pfnProfileLoadString (name, "FixedPoints", key, "");\r
-        if (strlen (text))\r
-        {\r
-          xyz[i][j].fixed = 1;\r
-          xyz[i][j].rate        = 0.;\r
-          sscanf(text,"%g %g %g",&value,&range,&rate);\r
-          xyz[i][j].fixed_value = value;\r
-          xyz[i][j].range       = range;\r
-          xyz[i][j].rate        = rate;\r
-        }\r
-        else\r
-          xyz[i][j].fixed = 0;\r
-      }\r
-    }\r
-  }\r
-}\r
+/*
+GenSurf plugin for GtkRadiant
+Copyright (C) 2001 David Hyde, Loki software and qeradiant.com
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <gtk/gtk.h>
+#include <stdio.h>
+#include <stdlib.h>
+/*
+#include <string.h>
+#include <tchar.h>
+#include <math.h>
+*/
+#include "gensurf.h"
+
+char      gszAppDir[NAME_MAX];
+char      gszCaption[64];
+char      gszIni[NAME_MAX];
+char      gszHelpFile[NAME_MAX];
+char      gszMapFile[NAME_MAX];
+char      gszVersion[64];
+double    Amplitude;
+double    Roughness;
+double    TexOffset[2];
+double    TexScale[2];
+double    WaveLength;
+double    Hll, Hur, Vll, Vur;
+double    Z00, Z01, Z10, Z11;
+ELEMENT   Vertex[(MAX_ROWS+1)*(MAX_ROWS+1)];
+int       AddHints;
+int       ArghRad2;
+int       AutoOverwrite;
+int       Decimate=0;
+int                            SnapToGrid=0; // 0, or the grid size to snap to. // Hydra : snap to grid
+int       FileAppend=0;
+int       FixBorders;
+int       HideBackFaces=0;
+int       NH, NV;
+int       NumVerticesSelected;
+int       Plane;
+int       Preview;
+int       RandomSeed=1;
+int       Skybox;
+int       UseDetail;
+int       UseLadder;
+int       VertexMode=0;
+int       WaveType;
+int       gNumNodes=0;
+int       gNumTris=0;
+int       vid_x, vid_y;
+int       view_x, view_y;
+int       view_cx, view_cy;
+int       UsePatches;
+int       SlantAngle;
+int       GimpHints;
+int                            Antialiasing; // ^Fishman - Antializing for the preview window.
+int                            AddTerrainKey; // ^Fishman - Add terrain key to func_group.
+int                            SP; // ^Fishman - Snap to grid.
+
+GtkWidget *g_pWnd;        // ghwnd;
+GtkWidget *g_pRadiantWnd; // ghwnd_main;
+/*HWND      ghwndAngles;
+*/GtkWidget *g_pWndPreview;
+GtkWidget *g_pPreviewWidget;
+MYBITMAP  gbmp;
+NODE      *gNode=(NODE *)NULL;
+TRI       *gTri=(TRI *)NULL;
+
+int       Game;
+bounding_box PlayerBox[NUMGAMES] = { {{-16., 16.}, {-16., 16.}, {-24., 32.}},    // Quake2
+                                     {{-16., 16.}, {-16., 16.}, {-36., 36.}},    // Half-Life
+                                     {{-16., 16.}, {-16., 16.}, {-32., 32.}},    // SiN
+                                     {{-16., 16.}, {-16., 16.}, {-24., 32.}},    // Heretic2 (guess)
+                                     {{-16., 16.}, {-16., 16.}, {-24., 32.}},    // KingPin (guess)
+                                     {{-30., 30.}, {-30., 30.}, {-10.,160.}},   // Genesis3D (no idea)
+                                     {{-16., 16.}, {-16., 16.}, {-24., 32.}}};  // Quake3 (not sure)
+//char      gszOutputDir[NUMGAMES][NAME_MAX];
+//char      gszTextureDir[NUMGAMES][NAME_MAX];
+char      Texture[NUMGAMES][3][64];
+//char      pakfile[NUMGAMES][NAME_MAX];
+//char      lastpakfile[NUMGAMES][NAME_MAX];
+//int       UsePak[NUMGAMES];
+//char      GameDir[NUMGAMES][NAME_MAX];
+
+char GameName[NUMGAMES][16] = {"Quake2", "Half-Life", "SiN", "Heretic2", "Kingpin", "Genesis3D", "Quake3" };
+
+
+bool GenSurfInit ()
+{
+  strcpy (gszVersion, "1.05");
+  strcpy (gszCaption, "GtkGenSurf");
+  if (strlen (gszVersion))
+  {
+    strcat (gszCaption, " v");
+    strcat (gszCaption, gszVersion);
+  }
+
+  strcpy (gszIni, g_FuncTable.m_pfnProfileGetDirectory ());
+  strcat (gszIni, "gensurf.ini");
+
+/*if (g_FuncTable.m_pfnReadProjectKey != NULL)
+  {
+    char *basepath;
+
+    basepath = g_FuncTable.m_pfnReadProjectKey("basepath");
+    if (basepath)
+    {
+      g_strdown (basepath);
+      if (strstr(basepath,"baseq3"))
+        Game = QUAKE3;
+      else if (strstr (basepath,"baseq2"))
+        Game = QUAKE2;
+      else // Gotta have a game, might as well be Quake3
+        Game = QUAKE3;
+    }
+    else
+      Game = QUAKE3;
+  }
+  else */
+    Game = QUAKE3;
+
+  ReadIniFile (gszIni);
+
+  if (g_pWnd == NULL)
+    g_pWnd = create_main_dialog ();
+
+  return true;
+}
+
+// Reads default values
+
+#define OPTS_SECTION "Options"
+
+void ReadIniFile (const char *file)
+{
+  char *Text;
+  float x1,x2,x3,x4;
+  int   i;
+
+  Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "Amplitude", "");
+  if (strlen (Text))
+    Amplitude = atof (Text);
+  else
+    Amplitude = 128;
+
+  Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "Roughness", "");
+  if (strlen (Text))
+    Roughness = atof (Text);
+  else
+    Roughness = 16;
+
+  Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "WaveLength", "");
+  if (strlen (Text))
+    WaveLength = atof (Text);
+  else
+    WaveLength = 1024;
+
+  Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "Extents", "");
+  if (strlen (Text))
+  {
+    sscanf(Text,"%f,%f,%f,%f",&x1,&x2,&x3,&x4);
+    Hll = x1;
+    Vll = x2;
+    Hur = x3;
+    Vur = x4;
+  }
+  else
+  {
+    Hll = -512;
+    Vll = -512;
+    Hur =  512;
+    Vur =  512;
+  }
+
+  Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "CornerValues", "");
+  if (strlen (Text))
+  {
+    sscanf(Text,"%f,%f,%f,%f",&x1,&x2,&x3,&x4);
+    Z00 = x1;
+    Z01 = x2;
+    Z10 = x3;
+    Z11 = x4;
+  }
+  else
+  {
+    Z00 = 0.;
+    Z01 = 0.;
+    Z10 = 0.;
+    Z11 = 0.;
+  }
+
+  Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "TextureOffset", "");
+  if (strlen (Text))
+  {
+    sscanf(Text,"%f,%f",&x1,&x2);
+    TexOffset[0] = x1;
+    TexOffset[1] = x2;
+  }
+  else
+  {
+    TexOffset[0] = 0.;
+    TexOffset[1] = 0.;
+  }
+
+  Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION,"TextureScale","");
+  if (strlen (Text))
+  {
+    sscanf(Text,"%f,%f",&x1,&x2);
+    TexScale[0] = x1;
+    TexScale[1] = x2;
+    if(TexScale[0] == 0.) TexScale[0] = 1.0;
+    if(TexScale[1] == 0.) TexScale[1] = 1.0;
+  }
+  else
+  {
+    TexScale[0] = 1.;
+    TexScale[1] = 1.;
+  }
+
+  NH = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"NH",8);
+  NH = max(1,min(NH,MAX_ROWS));
+  NV = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"NV",8);
+  NV = max(1,min(NV,MAX_ROWS));
+
+//     Decimate   = GetPrivateProfileInt(OPTS_SECTION,"Decimate",0,file);
+//     Decimate = max(0,min(Decimate,100));
+
+  AddHints                     = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"AddHints",0);
+  ArghRad2                     = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"ArghRad2",0);
+  AutoOverwrite        = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"AutoOverwrite",0);
+  FixBorders           = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"FixBorders",1);
+  HideBackFaces        = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"HideBackFaces",0);
+  Plane                                        = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"Plane",0);
+  Preview                              = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"Preview", 0);
+       Antialiasing    = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"Antialiasing",0); // ^Fishman - Antializing for the preview window.
+  RandomSeed           = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"RandomSeed",1);
+  Skybox                               = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"Skybox",0);
+  UseDetail                    = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"UseDetail",0);
+       AddTerrainKey   =       g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"AddTerrainKey",0); // ^Fishman - Add terrain key to func_group.
+  UseLadder                    = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"UseLadder",0);
+  WaveType                     = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"WaveType",0);
+  vid_x                                        = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"vid_x", 0);
+  vid_y                                        = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"vid_y", 0);
+  view_x                               = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"view_x",0);
+  view_y                               = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"view_y",0);
+  view_cx                              = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"view_cx",0);
+  view_cy                              = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"view_cy",0);
+
+  UsePatches           = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"UsePatches",0);
+
+  SlantAngle = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"SlantAngle",60);
+  GimpHints  = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"GimpHints",0);
+
+  for(i=0; i<NUMGAMES; i++)
+  {
+    //    strcpy (gszOutputDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"OutputDir",""));
+    strcpy (Texture[i][0], g_FuncTable.m_pfnProfileLoadString (file, GameName[i], "Texture", ""));
+    strcpy (Texture[i][1], g_FuncTable.m_pfnProfileLoadString (file, GameName[i], "Texture2", ""));
+    strcpy (Texture[i][2], g_FuncTable.m_pfnProfileLoadString (file, GameName[i], "Texture3", ""));
+    //    strcpy (gszTextureDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"TextureDir",""));
+    //    UsePak[i] = GetPrivateProfileInt(GameName[i],"UsePak",0);
+    //    strcpy (pakfile[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"PakFile",""));
+    //    strcpy (lastpakfile[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"LastPakFile",""));
+    //    strcpy (GameDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"GameDir","\0"));
+  }
+  /*
+       if(!strlen(gszTextureDir[QUAKE2]))
+               strcpy(gszTextureDir[QUAKE2],"c:\\quake2\\baseq2\\textures\\");
+       if(!strlen(gszTextureDir[KINGPIN]))
+               strcpy(gszTextureDir[KINGPIN],"c:\\kingpin\\main\\textures\\");
+  */
+  if(!strlen(Texture[QUAKE2][0]))    strcpy(Texture[QUAKE2][0],   "textures/e1u1/grass1_4");
+  if(!strlen(Texture[HALFLIFE][0]))  strcpy(Texture[HALFLIFE][0], "textures/OUT_GRND1");
+  if(!strlen(Texture[SIN][0]))       strcpy(Texture[SIN][0],      "textures/generic/floor_organic/fl_grass");
+  if(!strlen(Texture[HERETIC2][0]))  strcpy(Texture[HERETIC2][0], "textures/canyon/canyon05");
+  if(!strlen(Texture[KINGPIN][0]))   strcpy(Texture[KINGPIN][0],  "textures/bricks/s_sr_m3");
+  if(!strlen(Texture[GENESIS3D][0])) strcpy(Texture[GENESIS3D][0],"textures/rock13");
+  if(!strlen(Texture[QUAKE3][0]))    strcpy(Texture[QUAKE3][0],   "textures/organics/grass3");
+  if(!strlen(Texture[QUAKE3][1]))    strcpy(Texture[QUAKE3][1],   "textures/common/caulk");
+
+  strcpy (gbmp.name, g_FuncTable.m_pfnProfileLoadString (file, "Bitmap","Filename",""));
+
+  if (strlen(gbmp.name))
+    OpenBitmap ();
+
+  strcpy (gbmp.defpath, g_FuncTable.m_pfnProfileLoadString (file, "Bitmap","DefaultPath",""));
+
+  Text = g_FuncTable.m_pfnProfileLoadString (file, "Bitmap","BlackValue","");
+  if (strlen (Text))
+    gbmp.black_value = atof (Text);
+  else
+    gbmp.black_value = 0;
+
+  Text = g_FuncTable.m_pfnProfileLoadString (file, "Bitmap","WhiteValue","");
+  if (strlen (Text))
+    gbmp.white_value = atof (Text);
+  else
+    gbmp.white_value = 256.;
+}
+
+/*
+============
+va
+
+does a varargs printf into a temp buffer, so I don't need to have
+varargs versions of all text functions.
+FIXME: make this buffer size safe someday
+============
+*/
+char *va (char *format, ...)
+{
+  va_list argptr;
+  static char string[1024];
+
+  va_start (argptr, format);
+  vsprintf (string, format,argptr);
+  va_end (argptr);
+
+  return string;       
+}
+
+
+// Writes current values to INI file
+void WriteIniFile(const char *file)
+{
+  int i;
+
+  g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "Amplitude",    va("%g",Amplitude));
+  g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "Roughness",    va("%g",Roughness));
+  g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "WaveLength",   va("%g",WaveLength));
+  g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "Extents",      va("%g,%g,%g,%g",Hll,Vll,Hur,Vur));
+  g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "CornerValues", va("%g,%g,%g,%g",Z00,Z01,Z10,Z11));
+  g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "TextureOffset",va("%g,%g",TexOffset[0],TexOffset[1]));
+  g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "TextureScale", va("%g,%g",TexScale[0],TexScale[1]));
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "NH", NH);
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "NV", NV);
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "AddHints", AddHints);
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "ArghRad2", ArghRad2);
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "AutoOverwrite", AutoOverwrite);
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "FixBorders", FixBorders);
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "Plane", Plane);
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "Preview", Preview);
+       g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "Antialiasing", Antialiasing); // ^Fishman - Antializing for the preview window.
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "RandomSeed", RandomSeed);
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "Skybox", Skybox);
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "UseDetail", UseDetail);
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "AddTerrainKey", AddTerrainKey); // ^Fishman - Add terrain key to func_group.
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "UseLadder", UseLadder);
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "WaveType", WaveType);
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "vid_x", vid_x);
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "vid_y", vid_y);
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "view_x", view_x);
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "view_y", view_y);
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "view_cx", view_cx);
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "view_cy", view_cy);
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "UsePatches", UsePatches);
+  g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "SlantAngle", SlantAngle);
+  for(i=0; i<NUMGAMES; i++)
+  {
+    g_FuncTable.m_pfnProfileSaveString (file, GameName[i], "Texture",   Texture[i][0] );
+    g_FuncTable.m_pfnProfileSaveString (file, GameName[i], "Texture2",  Texture[i][1] );
+    g_FuncTable.m_pfnProfileSaveString (file, GameName[i], "Texture3",  Texture[i][2] );
+  }
+
+  g_FuncTable.m_pfnProfileSaveString (file, "Bitmap", "Filename", gbmp.name );
+  g_FuncTable.m_pfnProfileSaveString (file, "Bitmap", "DefaultPath", gbmp.defpath );
+  g_FuncTable.m_pfnProfileSaveString (file, "Bitmap", "BlackValue", va("%g",gbmp.black_value));
+  g_FuncTable.m_pfnProfileSaveString (file, "Bitmap", "WhiteValue", va("%g",gbmp.white_value));
+//g_FuncTable.m_pfnProfileSaveString (file, "Formula", "Formula", ExcelFunc );
+}
+
+void UpdatePreview (bool DataChange)
+{
+  if (g_pWndPreview && GTK_WIDGET_VISIBLE (g_pWndPreview))
+  {
+    if (DataChange)
+      GenerateXYZ ();
+
+    gtk_widget_draw (g_pPreviewWidget, NULL);
+  }
+}
+
+void SaveSetup (GtkWidget *parent)
+{
+  const char *name = g_FuncTable.m_pfnFileDialog (parent, false, "Save GenSurf Settings",
+                                             g_FuncTable.m_pfnProfileGetDirectory ());
+
+  if (name != NULL)
+  {
+    char key[32], text[32]; 
+    int i, j;
+
+    WriteIniFile (name);
+    g_FuncTable.m_pfnProfileSaveString (name, OPTS_SECTION,"MapFile",gszMapFile);
+    sprintf(text,"0x%04x",FileAppend);
+    g_FuncTable.m_pfnProfileSaveString (name, OPTS_SECTION,"Append",text);
+    sprintf(text,"0x%04x",Decimate);
+    g_FuncTable.m_pfnProfileSaveString (name, OPTS_SECTION,"Decimate",text);
+    for(i=0; i<=NH; i++)
+    {
+      for(j=0; j<=NV; j++)
+      {
+        if(xyz[i][j].fixed)
+        {
+          sprintf(key,"I%dJ%d",i,j);
+          sprintf(text,"%g %g %g", xyz[i][j].fixed_value, xyz[i][j].range, xyz[i][j].rate);
+          g_FuncTable.m_pfnProfileSaveString (name, "FixedPoints",key,text);
+        }
+      }
+    }
+  }
+}
+
+void OpenSetup (GtkWidget *parent, int UseDefaults)
+{
+  const char *name;
+  char key[32], *text;
+  float value,range,rate;
+  int i, j;
+
+  if (UseDefaults)
+    name = g_strdup ("plugins/defaults.srf"); // dummy string
+  else
+    name = g_FuncTable.m_pfnFileDialog (parent, true, "Open GenSurf Settings",
+                                        g_FuncTable.m_pfnProfileGetDirectory ());
+
+  if(name != NULL)
+  {
+    ReadIniFile (name);
+    Decimate   = g_FuncTable.m_pfnProfileLoadInt (name, OPTS_SECTION,"Decimate",0);
+    Decimate   = max(0,min(Decimate,100));
+
+    for (i=0; i<=NH; i++)
+    {
+      for (j=0; j<=NV; j++)
+      {
+        sprintf(key,"I%dJ%d",i,j);
+        text = g_FuncTable.m_pfnProfileLoadString (name, "FixedPoints", key, "");
+        if (strlen (text))
+        {
+          xyz[i][j].fixed = 1;
+          xyz[i][j].rate        = 0.;
+          sscanf(text,"%g %g %g",&value,&range,&rate);
+          xyz[i][j].fixed_value = value;
+          xyz[i][j].range       = range;
+          xyz[i][j].rate        = rate;
+        }
+        else
+          xyz[i][j].fixed = 0;
+      }
+    }
+  }
+}