apply misc fixes from Markus Fischer and Rambetter
[xonotic/netradiant.git] / radiant / brushscript.cpp
index 3fa141d3539d4bda3dcae5cea157938575a2fd64..68892fc2280f69e67ab666982e37b4a6c3888ea8 100644 (file)
-/*\r
-Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
-For a list of contributors, see the accompanying CONTRIBUTORS file.\r
-\r
-This file is part of GtkRadiant.\r
-\r
-GtkRadiant is free software; you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-\r
-GtkRadiant 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\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with GtkRadiant; if not, write to the Free Software\r
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
-*/\r
-\r
-// BrushScript stuff\r
-//\r
-\r
-/*!\r
-\todo is this still used / in working state?\r
-should we cleanup and remove it for good\r
-*/\r
-\r
-#include "stdafx.h"\r
-#include "gtkmisc.h"\r
-\r
-//\r
-struct SVariableDef\r
-{\r
-  CString m_strName;\r
-  CString m_strInput;\r
-  float m_fValue;\r
-};\r
-\r
-struct SVecVariableDef\r
-{\r
-  CString m_strName;\r
-  CString m_strInput;\r
-  vec3_t m_vValue;\r
-};\r
-\r
-\r
-\r
-const int MAX_VARIABLES = 64;\r
-\r
-brush_t* g_pHold1 = NULL;\r
-brush_t* g_pHold2 = NULL;\r
-brush_t* g_pHold3 = NULL;\r
-bool g_bRotateAroundSelection;\r
-int g_nVariableCount;\r
-int g_nVecVariableCount;\r
-int g_nLoopCounter;\r
-float g_fDefault = 9999.9f;\r
-vec3_t g_vDefault;\r
-bool g_bStartLoop;\r
-char* g_pLooper;\r
-bool g_bKeepGoing;\r
-\r
-SVariableDef g_Variables[MAX_VARIABLES];\r
-SVecVariableDef g_VecVariables[MAX_VARIABLES];\r
-\r
-void InitForScriptRun()\r
-{\r
-  g_pHold1 = NULL;\r
-  g_pHold2 = NULL;\r
-  g_pHold3 = NULL;\r
-  g_bRotateAroundSelection = true;\r
-  g_nVariableCount = 0;\r
-  g_nVecVariableCount = 0;\r
-  g_nLoopCounter = 0;\r
-  g_bStartLoop = false;\r
-  g_pLooper = NULL;\r
-  g_bKeepGoing = true;\r
-}\r
-\r
-void AddVariable(const char* pName, float fValue, const char* pInput = NULL)\r
-{\r
-  if (g_nVariableCount < MAX_VARIABLES)\r
-  {\r
-    g_Variables[g_nVariableCount].m_strName = pName;\r
-    g_Variables[g_nVariableCount].m_strName.MakeLower();\r
-    g_Variables[g_nVariableCount].m_fValue = fValue;\r
-    if (pInput)\r
-      g_Variables[g_nVariableCount].m_strInput = pInput;\r
-    g_nVariableCount++;\r
-  }\r
-  else\r
-    gtk_MessageBox(g_pParentWnd->m_pWidget, "Maximum script variable limit reached!");\r
-}\r
-\r
-float VariableValue(const char* pName)\r
-{\r
-  CString strName = pName;\r
-  strName.MakeLower();\r
-  for (int n = 0; n < g_nVariableCount; n++)\r
-  {\r
-    if (strName == g_Variables[n].m_strName)\r
-      return g_Variables[n].m_fValue;\r
-  }\r
-  //strName.Format("Reference to non-existant varirable %s", pName);\r
-  //g_pParentWnd->MessageBox(strName);\r
-  return g_fDefault;\r
-}\r
-\r
-void SetVariableValue(const char* pName, float fValue)\r
-{\r
-  CString strName = pName;\r
-  strName.MakeLower();\r
-  for (int n = 0; n < g_nVariableCount; n++)\r
-  {\r
-    if (strName == g_Variables[n].m_strName)\r
-      g_Variables[n].m_fValue = fValue;\r
-  }\r
-}\r
-\r
-\r
-\r
-void AddVectorVariable(const char* pName, const char* pInput = NULL)\r
-{\r
-  if (g_nVecVariableCount < MAX_VARIABLES)\r
-  {\r
-    g_VecVariables[g_nVecVariableCount].m_strName = pName;\r
-    g_VecVariables[g_nVecVariableCount].m_strName.MakeLower();\r
-    if (pInput)\r
-      g_VecVariables[g_nVariableCount].m_strInput = pInput;\r
-    g_nVecVariableCount++;\r
-  }\r
-  else\r
-    gtk_MessageBox(g_pParentWnd->m_pWidget, "Maximum script variable limit reached!");\r
-}\r
-\r
-void VectorVariableValue(const char* pName, vec3_t& v)\r
-{\r
-  CString strName = pName;\r
-  strName.MakeLower();\r
-  for (int n = 0; n < g_nVecVariableCount; n++)\r
-  {\r
-    if (strName == g_VecVariables[n].m_strName)\r
-    {\r
-      VectorCopy(g_VecVariables[n].m_vValue, v);\r
-      return;\r
-    }\r
-  }\r
-  strName.Format("Reference to non-existant variable %s", pName);\r
-  gtk_MessageBox(g_pParentWnd->m_pWidget, strName);\r
-}\r
-\r
-void SetVectorVariableValue(const char* pName, vec3_t v)\r
-{\r
-  CString strName = pName;\r
-  strName.MakeLower();\r
-  for (int n = 0; n < g_nVecVariableCount; n++)\r
-  {\r
-    if (strName == g_VecVariables[n].m_strName)\r
-      VectorCopy(v, g_VecVariables[n].m_vValue);\r
-  }\r
-}\r
-\r
-\r
-\r
-\r
-\r
-// commands\r
-//\r
-// _CopySelected(nHoldPos)  \r
-// copies selected brush to hold spot 1, 2 or 3\r
-//\r
-// _MoveSelected(x, y, z)\r
-// moves selected brush by coords provided\r
-//\r
-// _RotateSelected(x, y, z)\r
-// rotates selected brush by coords provided\r
-//\r
-// _MoveHold(nHoldPos, x, y, z)\r
-// moves brush in hold pos by coords provided\r
-//\r
-// _RotateHold(nHoldPos, x, y, z)\r
-// rotates brush in hold pos by coords provided\r
-//\r
-// _CopyToMap(nHoldPos)\r
-// copies hold brush to map\r
-//\r
-// _CopyAndSelect(nHoldPos)\r
-// copies hold brush to map and selects it\r
-//\r
-// _Input(VarName1, ... VarNamennn)\r
-// inputs a list of values from the user\r
-//\r
-\r
-typedef void (PFNScript)(char*&);\r
-\r
-\r
-struct SBrushScript\r
-{\r
-  const char* m_pName;\r
-  PFNScript* m_pProc;\r
-};\r
-\r
-\r
-const char* GetParam(char*& pBuffer)\r
-{\r
-  static CString strParam;\r
-  bool bStringMode = false;\r
-\r
-  while (*pBuffer != (char)NULL && isspace(*pBuffer))   // skip and whitespace\r
-    pBuffer++;\r
-\r
-  if (*pBuffer == '(') // if it's an opening paren, skip it\r
-    pBuffer++;\r
-\r
-  if (*pBuffer == '\"') // string ?\r
-  {\r
-    pBuffer++;\r
-    bStringMode = true;\r
-  }\r
-\r
-  strParam = "";\r
-\r
-  if (bStringMode)\r
-  {\r
-    while (*pBuffer != (char)NULL && *pBuffer != '\"')\r
-      strParam += *pBuffer++;\r
-  }\r
-  else\r
-  {\r
-    while (*pBuffer != (char)NULL && *pBuffer != ' ' && *pBuffer != ')' && *pBuffer != ',')\r
-      strParam += *pBuffer++;\r
-  }\r
-\r
-  if (*pBuffer != (char)NULL)   // skip last char\r
-    pBuffer++;\r
-\r
-  if (strParam.GetLength() > 0)\r
-  {\r
-    if (strParam.GetAt(0) == '$') // ? variable name\r
-    {\r
-      float f = VariableValue(strParam);\r
-      if (f != g_fDefault)\r
-        strParam.Format("%f", f);\r
-    }\r
-  }\r
-\r
-  return strParam;\r
-}\r
-\r
-brush_t* CopyBrush(brush_t* p)\r
-{                            \r
-  brush_t* pCopy = Brush_Clone(p);\r
-       //Brush_AddToList (pCopy, &active_brushes);\r
-       //Entity_LinkBrush (world_entity, pCopy);\r
-       Brush_Build(pCopy, false);\r
-\r
-  return pCopy;\r
-}\r
-\r
-\r
-void CopySelected(char*& pBuffer)\r
-{\r
-  // expects one param\r
-  CString strParam = GetParam(pBuffer);\r
-  int n = atoi(strParam);\r
-\r
-  brush_t* pCopy = NULL;\r
-  if (selected_brushes.next != &selected_brushes && \r
-      selected_brushes.next->next == &selected_brushes)\r
-    pCopy = selected_brushes.next;\r
-\r
-  if (pCopy)\r
-  {\r
-    if (n == 1)\r
-    {\r
-      //if (g_pHold1)\r
-        //Brush_Free(g_pHold1);\r
-      g_pHold1 = CopyBrush(pCopy);\r
-    }\r
-    else if (n == 2)\r
-    {\r
-      //if (g_pHold2)\r
-        //Brush_Free(g_pHold2);\r
-      g_pHold2 = CopyBrush(pCopy);\r
-    }\r
-    else\r
-    {\r
-      //if (g_pHold3)\r
-        //Brush_Free(g_pHold3);\r
-      g_pHold3 = CopyBrush(pCopy);\r
-    }\r
-  }\r
-}\r
-\r
-void MoveSelected(char*& pBuffer)\r
-{\r
-  vec3_t v;\r
-  CString strParam = GetParam(pBuffer);\r
-  v[0] = atof(strParam);\r
-  strParam = GetParam(pBuffer);\r
-  v[1] = atof(strParam);\r
-  strParam = GetParam(pBuffer);\r
-  v[2] = atof(strParam);\r
-  Select_Move(v, false);\r
-  Sys_UpdateWindows(W_ALL);\r
-}\r
-\r
-void RotateSelected(char*& pBuffer)\r
-{\r
-  vec3_t v;\r
-\r
-  if (g_bRotateAroundSelection)\r
-  {\r
-    Select_GetTrueMid(v);\r
-    VectorCopy(v, g_pParentWnd->ActiveXY()->RotateOrigin());\r
-  }\r
-\r
-  CString strParam = GetParam(pBuffer);\r
-  v[0] = atof(strParam);\r
-  strParam = GetParam(pBuffer);\r
-  v[1] = atof(strParam);\r
-  strParam = GetParam(pBuffer);\r
-  v[2] = atof(strParam);\r
-  for (int i = 0; i < 3; i++)\r
-    if (v[i] != 0.0)\r
-      Select_RotateAxis(i, v[i], false , true);\r
-  Sys_UpdateWindows(W_ALL);\r
-}\r
-\r
-void MoveHold(char*& pBuffer)\r
-{\r
-  CString strParam = GetParam(pBuffer);\r
-  brush_t* pBrush = NULL;\r
-  int nHold = atoi(strParam);\r
-  if (nHold == 1)\r
-    pBrush = g_pHold1;\r
-  else if (nHold == 2)\r
-    pBrush = g_pHold2;\r
-  else \r
-    pBrush = g_pHold3;\r
-\r
-  if (pBrush)\r
-  {\r
-    vec3_t v;\r
-    strParam = GetParam(pBuffer);\r
-    v[0] = atof(strParam);\r
-    strParam = GetParam(pBuffer);\r
-    v[1] = atof(strParam);\r
-    strParam = GetParam(pBuffer);\r
-    v[2] = atof(strParam);\r
-               Brush_Move (pBrush, v, false);\r
-  }\r
-}\r
-\r
-void RotateHold(char*& pBuffer)\r
-{\r
-  CString strParam = GetParam(pBuffer);\r
-  brush_t* pBrush = NULL;\r
-  int nHold = atoi(strParam);\r
-  if (nHold == 1)\r
-    pBrush = g_pHold1;\r
-  else if (nHold == 2)\r
-    pBrush = g_pHold2;\r
-  else \r
-    pBrush = g_pHold3;\r
-\r
-  if (pBrush)\r
-  {\r
-    vec3_t v;\r
-    strParam = GetParam(pBuffer);\r
-    v[0] = atof(strParam);\r
-    strParam = GetParam(pBuffer);\r
-    v[1] = atof(strParam);\r
-    strParam = GetParam(pBuffer);\r
-    v[2] = atof(strParam);\r
-    for (int i = 0; i < 3; i++)\r
-      if (v[i] != 0.0)\r
-        Select_RotateAxis(i, v[i]);\r
-  }\r
-}\r
-\r
-void CopyToMap(char*& pBuffer)\r
-{\r
-  CString strParam = GetParam(pBuffer);\r
-  brush_t* pBrush = NULL;\r
-  int nHold = atoi(strParam);\r
-  if (nHold == 1)\r
-    pBrush = g_pHold1;\r
-  else if (nHold == 2)\r
-    pBrush = g_pHold2;\r
-  else \r
-    pBrush = g_pHold3;\r
-\r
-  if (pBrush)\r
-  {\r
-    Brush_AddToList(pBrush, &active_brushes);\r
-               Entity_LinkBrush (world_entity, pBrush);\r
-               Brush_Build(pBrush, false);\r
-               \r
-    Sys_UpdateWindows(W_ALL);\r
-  }\r
-}\r
-\r
-void CopyAndSelect(char*& pBuffer)\r
-{\r
-  CString strParam = GetParam(pBuffer);\r
-  brush_t* pBrush = NULL;\r
-  int nHold = atoi(strParam);\r
-  if (nHold == 1)\r
-    pBrush = g_pHold1;\r
-  else if (nHold == 2)\r
-    pBrush = g_pHold2;\r
-  else \r
-    pBrush = g_pHold3;\r
-\r
-  if (pBrush)\r
-  {\r
-    Select_Deselect();\r
-    Brush_AddToList(pBrush, &active_brushes);\r
-               Entity_LinkBrush (world_entity, pBrush);\r
-               Brush_Build(pBrush, false);\r
-\r
-       Select_Brush(pBrush);\r
-    Sys_UpdateWindows(W_ALL);\r
-  }\r
-}\r
-\r
-void Input(char*& pBuffer)\r
-{\r
-  bool bGo = false;\r
-  const char *fields[5] = { "", "", "", "", "" };\r
-  float values[5];\r
-\r
-  for (int n = 0; n < g_nVariableCount; n++)\r
-  {\r
-    if (g_Variables[n].m_strInput.GetLength() > 0)\r
-    {\r
-      bGo = true;\r
-      if (n < 5)\r
-      {\r
-        switch (n)\r
-        {\r
-          case 0 : fields[1] = g_Variables[n].m_strInput.GetBuffer (); break;\r
-          case 1 : fields[2] = g_Variables[n].m_strInput.GetBuffer (); break;\r
-          case 2 : fields[3] = g_Variables[n].m_strInput.GetBuffer (); break;\r
-          case 3 : fields[4] = g_Variables[n].m_strInput.GetBuffer (); break;\r
-          case 4 : fields[5] = g_Variables[n].m_strInput.GetBuffer (); break;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  if (bGo)\r
-  {\r
-    if (DoBSInputDlg (fields, values) == IDOK)\r
-    {\r
-      for (int n = 0; n < g_nVariableCount; n++)\r
-      {\r
-        if (g_Variables[n].m_strInput.GetLength() > 0)\r
-        {\r
-          if (n < 5)\r
-          {\r
-            switch (n)\r
-            {\r
-              case 0 : g_Variables[n].m_fValue = values[1]; break;\r
-              case 1 : g_Variables[n].m_fValue = values[2]; break;\r
-              case 2 : g_Variables[n].m_fValue = values[3]; break;\r
-              case 3 : g_Variables[n].m_fValue = values[4]; break;\r
-              case 4 : g_Variables[n].m_fValue = values[5]; break;\r
-            }\r
-          }\r
-        }\r
-      }\r
-    }\r
-    else g_bKeepGoing = false;\r
-  }\r
-}\r
-\r
-bool g_bWaiting;\r
-void _3DPointDone(bool b, int n)\r
-{\r
-  g_bWaiting = false;\r
-}\r
-\r
-void _3DPointInput(char*& pBuffer)\r
-{\r
-  CString strParam = GetParam(pBuffer);\r
-  CString strParam2 = GetParam(pBuffer);\r
-  ShowInfoDialog(strParam2);\r
-  AddVectorVariable(strParam, strParam2);\r
-  g_bWaiting = true;\r
-  AcquirePath(2, &_3DPointDone);\r
-  while (g_bWaiting)\r
-    gtk_main_iteration ();\r
-  HideInfoDialog();\r
-  SetVectorVariableValue(strParam, g_PathPoints[0]);\r
-}\r
-\r
-void SetRotateOrigin(char*& pBuffer)\r
-{\r
-  vec3_t v;\r
-  CString strParam = GetParam(pBuffer);\r
-  VectorVariableValue(strParam, v);\r
-  VectorCopy(v, g_pParentWnd->ActiveXY()->RotateOrigin());\r
-  g_bRotateAroundSelection = false;\r
-}\r
-\r
-void InputVar(char*& pBuffer)\r
-{\r
-  CString strParam = GetParam(pBuffer);\r
-  CString strParam2 = GetParam(pBuffer);\r
-  AddVariable(strParam, 0.0, strParam2);\r
-}\r
-\r
-void LoopCount(char*& pBuffer)\r
-{\r
-  CString strParam = GetParam(pBuffer);\r
-  g_nLoopCounter = atoi(strParam);\r
-  if (g_nLoopCounter == 0)\r
-    g_nLoopCounter = (int)VariableValue(strParam);\r
-  if (g_nLoopCounter > 0)\r
-    g_pLooper = pBuffer;\r
-}\r
-\r
-void LoopRun(char*& pBuffer)\r
-{\r
-  if (g_bStartLoop == true)\r
-  {\r
-    g_nLoopCounter--;\r
-    if (g_nLoopCounter == 0)\r
-    {\r
-      g_bStartLoop = false;\r
-      GetParam(pBuffer);\r
-    }\r
-    else\r
-      pBuffer = g_pLooper;\r
-  }\r
-  else\r
-  {\r
-    if (g_pLooper && g_nLoopCounter > 0)\r
-    {\r
-      g_bStartLoop = true;\r
-      pBuffer = g_pLooper;\r
-    }\r
-    else\r
-    {\r
-      GetParam(pBuffer);\r
-    }\r
-  }\r
-}\r
-\r
-\r
-void ConfirmMessage(char*& pBuffer)\r
-{\r
-  CString strParam = GetParam(pBuffer);\r
-  if (gtk_MessageBox(g_pParentWnd->m_pWidget, strParam, "Script Info", MB_OKCANCEL) == IDCANCEL)\r
-    g_bKeepGoing = false;\r
-}\r
-\r
-void Spherize(char*& pBuffer)\r
-{\r
-  g_bScreenUpdates = false;\r
-  for (int n = 0; n < 120; n += 36)\r
-  {\r
-    for (int i = 0; i < 360; i += 36)\r
-    {\r
-      Select_RotateAxis(0, i, false , true);\r
-      CSG_Subtract();\r
-    }\r
-    Select_RotateAxis(2, n, false , true);\r
-  }\r
-  g_bScreenUpdates = true;\r
-}\r
-\r
-void RunIt(char*& pBuffer);\r
-SBrushScript g_ScriptCmds[] =\r
-{\r
-  {"_CopySelected", &CopySelected},\r
-  {"_MoveSelected", &MoveSelected},\r
-  {"_RotateSelected", &RotateSelected},\r
-  {"_MoveHold", &MoveHold},\r
-  {"_RotateHold", &RotateHold},\r
-  {"_CopyToMap", &CopyToMap},\r
-  {"_CopyAndSelect", &CopyAndSelect},\r
-  {"_Input", &Input},\r
-  {"_3DPointInput", &_3DPointInput},\r
-  {"_SetRotateOrigin", &SetRotateOrigin},\r
-  {"_InputVar", &InputVar},\r
-  {"_LoopCount", &LoopCount},\r
-  {"_LoopRun", &LoopRun},\r
-  {"_ConfirmMessage", &ConfirmMessage},\r
-  {"_Spherize", &Spherize},\r
-  {"_RunScript", RunIt}\r
-};\r
-\r
-const int g_nScriptCmdCount = sizeof(g_ScriptCmds) / sizeof(SBrushScript);\r
-\r
-void RunScript(char* pBuffer)\r
-{\r
-  g_pHold1 = NULL;\r
-  g_pHold2 = NULL;\r
-  g_pHold3 = NULL;\r
-\r
-  while (g_bKeepGoing && pBuffer && *pBuffer)\r
-  {\r
-    while (*pBuffer != (char)NULL && *pBuffer != '_')\r
-      pBuffer++;\r
-\r
-    char* pTemp = pBuffer;\r
-    int nLen = 0;\r
-    while (*pTemp != (char)NULL && *pTemp != '(')\r
-    {\r
-      pTemp++;\r
-      nLen++;\r
-    }\r
-    if (*pBuffer != (char)NULL)\r
-    {\r
-      bool bFound = false;\r
-      for (int i = 0; i < g_nScriptCmdCount; i++)\r
-      {\r
-        //if (strnicmp(g_ScriptCmds[i].m_pName, pBuffer, strlen(g_ScriptCmds[i].m_pName)) ==  0)\r
-        if (strnicmp(g_ScriptCmds[i].m_pName, pBuffer, nLen) ==  0)\r
-        {\r
-          pBuffer += strlen(g_ScriptCmds[i].m_pName);\r
-          g_ScriptCmds[i].m_pProc(pBuffer);\r
-          if (g_bStartLoop)\r
-          {\r
-          }\r
-          bFound = true;\r
-          break;\r
-        }\r
-      }\r
-      if (!bFound)\r
-        pBuffer++;\r
-    }\r
-  }\r
-}\r
-\r
-\r
-void RunScriptByName(char* pBuffer, bool bInit)\r
-{\r
-  if (bInit)\r
-    InitForScriptRun();\r
-  char* pScript = new char[4096];\r
-  CString strINI;\r
-  strINI = g_strGameToolsPath;\r
-  strINI += "/scripts.ini";\r
-  CString strScript;\r
-  FILE *f;\r
-\r
-  f = fopen (strINI.GetBuffer(), "rt");\r
-  if (f != NULL)\r
-  {\r
-    char line[1024], *ptr;\r
-\r
-    // read section names\r
-    while (fgets (line, 1024, f) != 0)\r
-    {\r
-      if (line[0] != '[')\r
-       continue;\r
-\r
-      ptr = strchr (line, ']');\r
-      *ptr = '\0';\r
-\r
-      if (strcmp (line, pScript) == 0)\r
-      {\r
-       while (fgets (line, 1024, f) != 0)\r
-       {\r
-         if ((strchr (line, '=') == NULL) ||\r
-             strlen (line) == 0)\r
-           break;\r
-         strScript += line;\r
-       }\r
-       break;\r
-      }\r
-    }\r
-    fclose (f);\r
-  }\r
-  RunScript((char*)strScript.GetBuffer());\r
-}\r
-\r
-\r
-void RunIt(char*& pBuffer)\r
-{\r
-  brush_t* p1 = g_pHold1;\r
-  brush_t* p2 = g_pHold2;\r
-  brush_t* p3 = g_pHold3;\r
-\r
-  CString strParam = GetParam(pBuffer);\r
-  RunScriptByName((char*)strParam.GetBuffer(), false);\r
-\r
-  g_pHold3 = p3;\r
-  g_pHold2 = p2;\r
-  g_pHold1 = p1;\r
-}\r
-\r
+/*
+Copyright (C) 1999-2007 id Software, Inc. and contributors.
+For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+This file is part of GtkRadiant.
+
+GtkRadiant is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+GtkRadiant 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GtkRadiant; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+// BrushScript stuff
+//
+
+/*!
+\todo is this still used / in working state?
+should we cleanup and remove it for good
+*/
+
+#include "stdafx.h"
+#include "gtkmisc.h"
+
+//
+struct SVariableDef
+{
+  CString m_strName;
+  CString m_strInput;
+  float m_fValue;
+};
+
+struct SVecVariableDef
+{
+  CString m_strName;
+  CString m_strInput;
+  vec3_t m_vValue;
+};
+
+
+
+const int MAX_VARIABLES = 64;
+
+brush_t* g_pHold1 = NULL;
+brush_t* g_pHold2 = NULL;
+brush_t* g_pHold3 = NULL;
+bool g_bRotateAroundSelection;
+int g_nVariableCount;
+int g_nVecVariableCount;
+int g_nLoopCounter;
+float g_fDefault = 9999.9f;
+vec3_t g_vDefault;
+bool g_bStartLoop;
+char* g_pLooper;
+bool g_bKeepGoing;
+
+SVariableDef g_Variables[MAX_VARIABLES];
+SVecVariableDef g_VecVariables[MAX_VARIABLES];
+
+void InitForScriptRun()
+{
+  g_pHold1 = NULL;
+  g_pHold2 = NULL;
+  g_pHold3 = NULL;
+  g_bRotateAroundSelection = true;
+  g_nVariableCount = 0;
+  g_nVecVariableCount = 0;
+  g_nLoopCounter = 0;
+  g_bStartLoop = false;
+  g_pLooper = NULL;
+  g_bKeepGoing = true;
+}
+
+void AddVariable(const char* pName, float fValue, const char* pInput = NULL)
+{
+  if (g_nVariableCount < MAX_VARIABLES)
+  {
+    g_Variables[g_nVariableCount].m_strName = pName;
+    g_Variables[g_nVariableCount].m_strName.MakeLower();
+    g_Variables[g_nVariableCount].m_fValue = fValue;
+    if (pInput)
+      g_Variables[g_nVariableCount].m_strInput = pInput;
+    g_nVariableCount++;
+  }
+  else
+    gtk_MessageBox(g_pParentWnd->m_pWidget, "Maximum script variable limit reached!");
+}
+
+float VariableValue(const char* pName)
+{
+  CString strName = pName;
+  strName.MakeLower();
+  for (int n = 0; n < g_nVariableCount; n++)
+  {
+    if (strName == g_Variables[n].m_strName)
+      return g_Variables[n].m_fValue;
+  }
+  //strName.Format("Reference to non-existant varirable %s", pName);
+  //g_pParentWnd->MessageBox(strName);
+  return g_fDefault;
+}
+
+void SetVariableValue(const char* pName, float fValue)
+{
+  CString strName = pName;
+  strName.MakeLower();
+  for (int n = 0; n < g_nVariableCount; n++)
+  {
+    if (strName == g_Variables[n].m_strName)
+      g_Variables[n].m_fValue = fValue;
+  }
+}
+
+
+
+void AddVectorVariable(const char* pName, const char* pInput = NULL)
+{
+  if (g_nVecVariableCount < MAX_VARIABLES)
+  {
+    g_VecVariables[g_nVecVariableCount].m_strName = pName;
+    g_VecVariables[g_nVecVariableCount].m_strName.MakeLower();
+    if (pInput)
+      g_VecVariables[g_nVariableCount].m_strInput = pInput;
+    g_nVecVariableCount++;
+  }
+  else
+    gtk_MessageBox(g_pParentWnd->m_pWidget, "Maximum script variable limit reached!");
+}
+
+void VectorVariableValue(const char* pName, vec3_t& v)
+{
+  CString strName = pName;
+  strName.MakeLower();
+  for (int n = 0; n < g_nVecVariableCount; n++)
+  {
+    if (strName == g_VecVariables[n].m_strName)
+    {
+      VectorCopy(g_VecVariables[n].m_vValue, v);
+      return;
+    }
+  }
+  strName.Format("Reference to non-existant variable %s", pName);
+  gtk_MessageBox(g_pParentWnd->m_pWidget, strName);
+}
+
+void SetVectorVariableValue(const char* pName, vec3_t v)
+{
+  CString strName = pName;
+  strName.MakeLower();
+  for (int n = 0; n < g_nVecVariableCount; n++)
+  {
+    if (strName == g_VecVariables[n].m_strName)
+      VectorCopy(v, g_VecVariables[n].m_vValue);
+  }
+}
+
+
+
+
+
+// commands
+//
+// _CopySelected(nHoldPos)  
+// copies selected brush to hold spot 1, 2 or 3
+//
+// _MoveSelected(x, y, z)
+// moves selected brush by coords provided
+//
+// _RotateSelected(x, y, z)
+// rotates selected brush by coords provided
+//
+// _MoveHold(nHoldPos, x, y, z)
+// moves brush in hold pos by coords provided
+//
+// _RotateHold(nHoldPos, x, y, z)
+// rotates brush in hold pos by coords provided
+//
+// _CopyToMap(nHoldPos)
+// copies hold brush to map
+//
+// _CopyAndSelect(nHoldPos)
+// copies hold brush to map and selects it
+//
+// _Input(VarName1, ... VarNamennn)
+// inputs a list of values from the user
+//
+
+typedef void (PFNScript)(char*&);
+
+
+struct SBrushScript
+{
+  const char* m_pName;
+  PFNScript* m_pProc;
+};
+
+
+const char* GetParam(char*& pBuffer)
+{
+  static CString strParam;
+  bool bStringMode = false;
+
+  while (*pBuffer != (char)NULL && isspace(*pBuffer))   // skip and whitespace
+    pBuffer++;
+
+  if (*pBuffer == '(') // if it's an opening paren, skip it
+    pBuffer++;
+
+  if (*pBuffer == '\"') // string ?
+  {
+    pBuffer++;
+    bStringMode = true;
+  }
+
+  strParam = "";
+
+  if (bStringMode)
+  {
+    while (*pBuffer != (char)NULL && *pBuffer != '\"')
+      strParam += *pBuffer++;
+  }
+  else
+  {
+    while (*pBuffer != (char)NULL && *pBuffer != ' ' && *pBuffer != ')' && *pBuffer != ',')
+      strParam += *pBuffer++;
+  }
+
+  if (*pBuffer != (char)NULL)   // skip last char
+    pBuffer++;
+
+  if (strParam.GetLength() > 0)
+  {
+    if (strParam.GetAt(0) == '$') // ? variable name
+    {
+      float f = VariableValue(strParam);
+      if (f != g_fDefault)
+        strParam.Format("%f", f);
+    }
+  }
+
+  return strParam;
+}
+
+brush_t* CopyBrush(brush_t* p)
+{                            
+  brush_t* pCopy = Brush_Clone(p);
+       //Brush_AddToList (pCopy, &active_brushes);
+       //Entity_LinkBrush (world_entity, pCopy);
+       Brush_Build(pCopy, false);
+
+  return pCopy;
+}
+
+
+void CopySelected(char*& pBuffer)
+{
+  // expects one param
+  CString strParam = GetParam(pBuffer);
+  int n = atoi(strParam);
+
+  brush_t* pCopy = NULL;
+  if (selected_brushes.next != &selected_brushes && 
+      selected_brushes.next->next == &selected_brushes)
+    pCopy = selected_brushes.next;
+
+  if (pCopy)
+  {
+    if (n == 1)
+    {
+      //if (g_pHold1)
+        //Brush_Free(g_pHold1);
+      g_pHold1 = CopyBrush(pCopy);
+    }
+    else if (n == 2)
+    {
+      //if (g_pHold2)
+        //Brush_Free(g_pHold2);
+      g_pHold2 = CopyBrush(pCopy);
+    }
+    else
+    {
+      //if (g_pHold3)
+        //Brush_Free(g_pHold3);
+      g_pHold3 = CopyBrush(pCopy);
+    }
+  }
+}
+
+void MoveSelected(char*& pBuffer)
+{
+  vec3_t v;
+  CString strParam = GetParam(pBuffer);
+  v[0] = atof(strParam);
+  strParam = GetParam(pBuffer);
+  v[1] = atof(strParam);
+  strParam = GetParam(pBuffer);
+  v[2] = atof(strParam);
+  Select_Move(v, false);
+  Sys_UpdateWindows(W_ALL);
+}
+
+void RotateSelected(char*& pBuffer)
+{
+  vec3_t v;
+
+  if (g_bRotateAroundSelection)
+  {
+    Select_GetTrueMid(v);
+    VectorCopy(v, g_pParentWnd->ActiveXY()->RotateOrigin());
+  }
+
+  CString strParam = GetParam(pBuffer);
+  v[0] = atof(strParam);
+  strParam = GetParam(pBuffer);
+  v[1] = atof(strParam);
+  strParam = GetParam(pBuffer);
+  v[2] = atof(strParam);
+  for (int i = 0; i < 3; i++)
+    if (v[i] != 0.0)
+      Select_RotateAxis(i, v[i], false , true);
+  Sys_UpdateWindows(W_ALL);
+}
+
+void MoveHold(char*& pBuffer)
+{
+  CString strParam = GetParam(pBuffer);
+  brush_t* pBrush = NULL;
+  int nHold = atoi(strParam);
+  if (nHold == 1)
+    pBrush = g_pHold1;
+  else if (nHold == 2)
+    pBrush = g_pHold2;
+  else 
+    pBrush = g_pHold3;
+
+  if (pBrush)
+  {
+    vec3_t v;
+    strParam = GetParam(pBuffer);
+    v[0] = atof(strParam);
+    strParam = GetParam(pBuffer);
+    v[1] = atof(strParam);
+    strParam = GetParam(pBuffer);
+    v[2] = atof(strParam);
+               Brush_Move (pBrush, v, false);
+  }
+}
+
+void RotateHold(char*& pBuffer)
+{
+  CString strParam = GetParam(pBuffer);
+  brush_t* pBrush = NULL;
+  int nHold = atoi(strParam);
+  if (nHold == 1)
+    pBrush = g_pHold1;
+  else if (nHold == 2)
+    pBrush = g_pHold2;
+  else 
+    pBrush = g_pHold3;
+
+  if (pBrush)
+  {
+    vec3_t v;
+    strParam = GetParam(pBuffer);
+    v[0] = atof(strParam);
+    strParam = GetParam(pBuffer);
+    v[1] = atof(strParam);
+    strParam = GetParam(pBuffer);
+    v[2] = atof(strParam);
+    for (int i = 0; i < 3; i++)
+      if (v[i] != 0.0)
+        Select_RotateAxis(i, v[i]);
+  }
+}
+
+void CopyToMap(char*& pBuffer)
+{
+  CString strParam = GetParam(pBuffer);
+  brush_t* pBrush = NULL;
+  int nHold = atoi(strParam);
+  if (nHold == 1)
+    pBrush = g_pHold1;
+  else if (nHold == 2)
+    pBrush = g_pHold2;
+  else 
+    pBrush = g_pHold3;
+
+  if (pBrush)
+  {
+    Brush_AddToList(pBrush, &active_brushes);
+               Entity_LinkBrush (world_entity, pBrush);
+               Brush_Build(pBrush, false);
+               
+    Sys_UpdateWindows(W_ALL);
+  }
+}
+
+void CopyAndSelect(char*& pBuffer)
+{
+  CString strParam = GetParam(pBuffer);
+  brush_t* pBrush = NULL;
+  int nHold = atoi(strParam);
+  if (nHold == 1)
+    pBrush = g_pHold1;
+  else if (nHold == 2)
+    pBrush = g_pHold2;
+  else 
+    pBrush = g_pHold3;
+
+  if (pBrush)
+  {
+    Select_Deselect();
+    Brush_AddToList(pBrush, &active_brushes);
+               Entity_LinkBrush (world_entity, pBrush);
+               Brush_Build(pBrush, false);
+
+       Select_Brush(pBrush);
+    Sys_UpdateWindows(W_ALL);
+  }
+}
+
+void Input(char*& pBuffer)
+{
+  bool bGo = false;
+  const char *fields[5] = { "", "", "", "", "" };
+  float values[5];
+
+  for (int n = 0; n < g_nVariableCount; n++)
+  {
+    if (g_Variables[n].m_strInput.GetLength() > 0)
+    {
+      bGo = true;
+      if (n < 5)
+      {
+        switch (n)
+        {
+          case 0 : fields[1] = g_Variables[n].m_strInput.GetBuffer (); break;
+          case 1 : fields[2] = g_Variables[n].m_strInput.GetBuffer (); break;
+          case 2 : fields[3] = g_Variables[n].m_strInput.GetBuffer (); break;
+          case 3 : fields[4] = g_Variables[n].m_strInput.GetBuffer (); break;
+          case 4 : fields[5] = g_Variables[n].m_strInput.GetBuffer (); break;
+        }
+      }
+    }
+  }
+
+  if (bGo)
+  {
+    if (DoBSInputDlg (fields, values) == IDOK)
+    {
+      for (int n = 0; n < g_nVariableCount; n++)
+      {
+        if (g_Variables[n].m_strInput.GetLength() > 0)
+        {
+          if (n < 5)
+          {
+            switch (n)
+            {
+              case 0 : g_Variables[n].m_fValue = values[1]; break;
+              case 1 : g_Variables[n].m_fValue = values[2]; break;
+              case 2 : g_Variables[n].m_fValue = values[3]; break;
+              case 3 : g_Variables[n].m_fValue = values[4]; break;
+              case 4 : g_Variables[n].m_fValue = values[5]; break;
+            }
+          }
+        }
+      }
+    }
+    else g_bKeepGoing = false;
+  }
+}
+
+bool g_bWaiting;
+void _3DPointDone(bool b, int n)
+{
+  g_bWaiting = false;
+}
+
+void _3DPointInput(char*& pBuffer)
+{
+  CString strParam = GetParam(pBuffer);
+  CString strParam2 = GetParam(pBuffer);
+  ShowInfoDialog(strParam2);
+  AddVectorVariable(strParam, strParam2);
+  g_bWaiting = true;
+  AcquirePath(2, &_3DPointDone);
+  while (g_bWaiting)
+    gtk_main_iteration ();
+  HideInfoDialog();
+  SetVectorVariableValue(strParam, g_PathPoints[0]);
+}
+
+void SetRotateOrigin(char*& pBuffer)
+{
+  vec3_t v;
+  CString strParam = GetParam(pBuffer);
+  VectorVariableValue(strParam, v);
+  VectorCopy(v, g_pParentWnd->ActiveXY()->RotateOrigin());
+  g_bRotateAroundSelection = false;
+}
+
+void InputVar(char*& pBuffer)
+{
+  CString strParam = GetParam(pBuffer);
+  CString strParam2 = GetParam(pBuffer);
+  AddVariable(strParam, 0.0, strParam2);
+}
+
+void LoopCount(char*& pBuffer)
+{
+  CString strParam = GetParam(pBuffer);
+  g_nLoopCounter = atoi(strParam);
+  if (g_nLoopCounter == 0)
+    g_nLoopCounter = (int)VariableValue(strParam);
+  if (g_nLoopCounter > 0)
+    g_pLooper = pBuffer;
+}
+
+void LoopRun(char*& pBuffer)
+{
+  if (g_bStartLoop == true)
+  {
+    g_nLoopCounter--;
+    if (g_nLoopCounter == 0)
+    {
+      g_bStartLoop = false;
+      GetParam(pBuffer);
+    }
+    else
+      pBuffer = g_pLooper;
+  }
+  else
+  {
+    if (g_pLooper && g_nLoopCounter > 0)
+    {
+      g_bStartLoop = true;
+      pBuffer = g_pLooper;
+    }
+    else
+    {
+      GetParam(pBuffer);
+    }
+  }
+}
+
+
+void ConfirmMessage(char*& pBuffer)
+{
+  CString strParam = GetParam(pBuffer);
+  if (gtk_MessageBox(g_pParentWnd->m_pWidget, strParam, "Script Info", MB_OKCANCEL) == IDCANCEL)
+    g_bKeepGoing = false;
+}
+
+void Spherize(char*& pBuffer)
+{
+  g_bScreenUpdates = false;
+  for (int n = 0; n < 120; n += 36)
+  {
+    for (int i = 0; i < 360; i += 36)
+    {
+      Select_RotateAxis(0, i, false , true);
+      CSG_Subtract();
+    }
+    Select_RotateAxis(2, n, false , true);
+  }
+  g_bScreenUpdates = true;
+}
+
+void RunIt(char*& pBuffer);
+SBrushScript g_ScriptCmds[] =
+{
+  {"_CopySelected", &CopySelected},
+  {"_MoveSelected", &MoveSelected},
+  {"_RotateSelected", &RotateSelected},
+  {"_MoveHold", &MoveHold},
+  {"_RotateHold", &RotateHold},
+  {"_CopyToMap", &CopyToMap},
+  {"_CopyAndSelect", &CopyAndSelect},
+  {"_Input", &Input},
+  {"_3DPointInput", &_3DPointInput},
+  {"_SetRotateOrigin", &SetRotateOrigin},
+  {"_InputVar", &InputVar},
+  {"_LoopCount", &LoopCount},
+  {"_LoopRun", &LoopRun},
+  {"_ConfirmMessage", &ConfirmMessage},
+  {"_Spherize", &Spherize},
+  {"_RunScript", RunIt}
+};
+
+const int g_nScriptCmdCount = sizeof(g_ScriptCmds) / sizeof(SBrushScript);
+
+void RunScript(char* pBuffer)
+{
+  g_pHold1 = NULL;
+  g_pHold2 = NULL;
+  g_pHold3 = NULL;
+
+  while (g_bKeepGoing && pBuffer && *pBuffer)
+  {
+    while (*pBuffer != (char)NULL && *pBuffer != '_')
+      pBuffer++;
+
+    char* pTemp = pBuffer;
+    int nLen = 0;
+    while (*pTemp != (char)NULL && *pTemp != '(')
+    {
+      pTemp++;
+      nLen++;
+    }
+    if (*pBuffer != (char)NULL)
+    {
+      bool bFound = false;
+      for (int i = 0; i < g_nScriptCmdCount; i++)
+      {
+        //if (strnicmp(g_ScriptCmds[i].m_pName, pBuffer, strlen(g_ScriptCmds[i].m_pName)) ==  0)
+        if (strnicmp(g_ScriptCmds[i].m_pName, pBuffer, nLen) ==  0)
+        {
+          pBuffer += strlen(g_ScriptCmds[i].m_pName);
+          g_ScriptCmds[i].m_pProc(pBuffer);
+          if (g_bStartLoop)
+          {
+          }
+          bFound = true;
+          break;
+        }
+      }
+      if (!bFound)
+        pBuffer++;
+    }
+  }
+}
+
+
+void RunScriptByName(char* pBuffer, bool bInit)
+{
+  if (bInit)
+    InitForScriptRun();
+  char* pScript = new char[4096];
+  CString strINI;
+  strINI = g_strGameToolsPath;
+  strINI += "/scripts.ini";
+  CString strScript;
+  FILE *f;
+
+  f = fopen (strINI.GetBuffer(), "rt");
+  if (f != NULL)
+  {
+    char line[1024], *ptr;
+
+    // read section names
+    while (fgets (line, 1024, f) != 0)
+    {
+      if (line[0] != '[')
+       continue;
+
+      ptr = strchr (line, ']');
+      *ptr = '\0';
+
+      if (strcmp (line, pScript) == 0)
+      {
+       while (fgets (line, 1024, f) != 0)
+       {
+         if ((strchr (line, '=') == NULL) ||
+             strlen (line) == 0)
+           break;
+         strScript += line;
+       }
+       break;
+      }
+    }
+    fclose (f);
+  }
+  RunScript((char*)strScript.GetBuffer());
+}
+
+
+void RunIt(char*& pBuffer)
+{
+  brush_t* p1 = g_pHold1;
+  brush_t* p2 = g_pHold2;
+  brush_t* p3 = g_pHold3;
+
+  CString strParam = GetParam(pBuffer);
+  RunScriptByName((char*)strParam.GetBuffer(), false);
+
+  g_pHold3 = p3;
+  g_pHold2 = p2;
+  g_pHold1 = p1;
+}
+