/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. #include "StdAfx.h" #if defined(WIN32) || defined(WIN64) #include "ConsoleHelpGen.h" #include "System.h" // remove bad characters, toupper, not very fast string CConsoleHelpGen::FixAnchorName(const char* szName) { string ret; const char* p = szName; while (*p) { if ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') || (*p >= '0' && *p <= '9')) { if (*p >= 'a' && *p <= 'z') { ret += *p - 'a' + 'A'; } else { ret += *p; } } ++p; } return ret; } string CConsoleHelpGen::GetCleanPrefix(const char* p) { string sRet; while (*p != '_' && *p != 0) { sRet += *p++; } return sRet; } string CConsoleHelpGen::SplitPrefixString_Part1(const char* p) { string sRet; while (*p != 10 && *p != 13 && *p != 0) { sRet += *p++; } return sRet; } const char* CConsoleHelpGen::SplitPrefixString_Part2(const char* p) { while (*p != 10 && *p != 13 && *p != 0) { p++; } while (*p == 10 || *p == 13) { p++; } return p; } void CConsoleHelpGen::StartPage(FILE* f, const char* szPageName, const char* szPageDescription) const { if (m_eWorkMode == eWM_HTML) { fprintf(f, "%s", szPageName); fprintf(f, "", szPageDescription); fprintf(f, ""); fprintf(f, ""); fprintf(f, ""); fprintf(f, ""); fprintf(f, ""); fprintf(f, ""); fprintf(f, ""); } } void CConsoleHelpGen::EndPage(FILE* f) const { if (m_eWorkMode == eWM_HTML) { fprintf(f, "

"); } } void CConsoleHelpGen::KeyValue(FILE* f, const char* szKey, const char* szValue) const { if (m_eWorkMode == eWM_HTML) { fprintf(f, "%s: %s
\n", szKey, szValue); } else if (m_eWorkMode == eWM_Confluence) { // fprintf(f,"*%s:* %s\n",szKey,szValue); fprintf(f, "| *%s:* | %s |\n", szKey, szValue); } else { assert(0); } } void CConsoleHelpGen::LogVersion(FILE* f) const { char s[1024]; { GetModuleFileName(NULL, s, sizeof(s)); char fdir[_MAX_PATH]; char fdrive[_MAX_PATH]; char file[_MAX_PATH]; char fext[_MAX_PATH]; _splitpath_s(s, fdrive, fdir, file, fext); KeyValue(f, "Executable", (string(file) + fext).c_str()); } { time_t ltime; time(<ime); tm today; localtime_s(&today, <ime); strftime(s, 128, "%c", &today); KeyValue(f, "Date(MM/DD/YY) Time", s); } { const SFileVersion& ver = gEnv->pSystem->GetFileVersion(); ver.ToString(s, sizeof(s)); KeyValue(f, "FileVersion", s); } { const SFileVersion& ver = gEnv->pSystem->GetProductVersion(); ver.ToString(s, sizeof(s)); KeyValue(f, "ProductVersion", s); } if (m_eWorkMode == eWM_HTML) { fprintf(f, "
\n"); } } void CConsoleHelpGen::StartH1(FILE* f, const char* szName) const { if (m_eWorkMode == eWM_HTML) { fprintf(f, "

%s

\n", szName); } else if (m_eWorkMode == eWM_Confluence) { fprintf(f, "h1. %s\n", szName); } else { assert(0); } } void CConsoleHelpGen::EndH1(FILE* f) const { if (m_eWorkMode == eWM_HTML) { fprintf(f, "
\n"); } } void CConsoleHelpGen::StartH3(FILE* f, const char* szName) const { if (m_eWorkMode == eWM_HTML) { fprintf(f, "

%s

\n"); } else if (m_eWorkMode == eWM_Confluence) { } else { assert(0); } } void CConsoleHelpGen::StartCVar(FILE* f, const char* szName) const { if (m_eWorkMode == eWM_HTML) { fprintf(f, "

%s

\n"); } else if (m_eWorkMode == eWM_Confluence) { fprintf(f, "\n\n"); } else { assert(0); } } void CConsoleHelpGen::SingleLinePrefix(FILE* f, const char* szPrefix, const char* szPrefixDesc, const char* szLink) const { // group within the list of all groups (no elements) if (m_eWorkMode == eWM_HTML) { fprintf(f, "
  • %s_ %s
  • \n", szLink, szPrefix, szPrefixDesc); } else if (m_eWorkMode == eWM_Confluence) { string sPrefix; if (*szPrefix) { sPrefix = string(szPrefix) + "_"; } // fprintf(f,"| %s | [%s|%s] |\n",sPrefix.c_str(),szPrefixDesc,szLink); // e.g. "" "CL_" "CC_" "I_" "T_" fprintf(f, "{section:border=false}\n" "{column:width=50px}{align:right}%s{align}{column}\n" "{column:width=10px}{column}\n" "{column}{align:left}[%s|%s]{align}{column}\n" "{section}\n", sPrefix.c_str(), szPrefixDesc, szLink); // e.g. "" "CL_" "CC_" "I_" "T_" } else { assert(0); } } void CConsoleHelpGen::StartPrefix(FILE* f, const char* szPrefix, const char* szPrefixDesc, const char* szLink) const { // group before all the group elements if (m_eWorkMode == eWM_HTML) { fprintf(f, "
  • %s_ %s
  • \n"); } } void CConsoleHelpGen::SingleLineEntry_InGlobal(FILE* f, const char* szName, const char* szLink) const { // element within a group if (m_eWorkMode == eWM_HTML) { fprintf(f, "
  • %s
  • \n", szLink, szName); } else if (m_eWorkMode == eWM_Confluence) { fprintf(f, "** [%s|%s]\n", szName, szLink); } else { assert(0); } } void CConsoleHelpGen::SingleLineEntry_InGroup(FILE* f, const char* szName, const char* szLink) const { // element within a group if (m_eWorkMode == eWM_HTML) { fprintf(f, "
  • %s
  • \n", szLink, szName); } else if (m_eWorkMode == eWM_Confluence) { fprintf(f, "* [%s|%s]\n", szName, szLink); } else { assert(0); } } // szName without # void CConsoleHelpGen::Anchor(FILE* f, const char* szName) const { if (m_eWorkMode == eWM_HTML) { fprintf(f, "\n", szName); } else if (m_eWorkMode == eWM_Confluence) { fprintf(f, "{anchor:%s}", szName); } else { assert(0); } } void CConsoleHelpGen::InsertConsoleVars(std::set& setCmdAndVars, const char* szLocalPrefix) const { CXConsole::ConsoleVariablesMap::const_iterator itrVar, itrVarEnd = m_rParent.m_mapVariables.end(); for (itrVar = m_rParent.m_mapVariables.begin(); itrVar != itrVarEnd; ++itrVar) { ICVar* var = itrVar->second; if (_strnicmp(var->GetName(), szLocalPrefix, strlen(szLocalPrefix)) == 0) { setCmdAndVars.insert(var->GetName()); } } } void CConsoleHelpGen::InsertConsoleCommands(std::set& setCmdAndVars, const char* szLocalPrefix) const { CXConsole::ConsoleCommandsMap::const_iterator itrCmd, itrCmdEnd = m_rParent.m_mapCommands.end(); for (itrCmd = m_rParent.m_mapCommands.begin(); itrCmd != itrCmdEnd; ++itrCmd) { const CConsoleCommand& cmd = itrCmd->second; if (_strnicmp(cmd.m_sName, szLocalPrefix, strlen(szLocalPrefix)) == 0) { setCmdAndVars.insert(cmd.m_sName.c_str()); } } } void CConsoleHelpGen::InsertConsoleVars(std::set& setCmdAndVars, std::map mapPrefix) const { CXConsole::ConsoleVariablesMap::const_iterator itrVar, itrVarEnd = m_rParent.m_mapVariables.end(); for (itrVar = m_rParent.m_mapVariables.begin(); itrVar != itrVarEnd; ++itrVar) { ICVar* var = itrVar->second; bool bInsert = true; { std::map::const_iterator it2, end = mapPrefix.end(); for (it2 = mapPrefix.begin(); it2 != end; ++it2) { if (it2->first != "___" && _strnicmp(var->GetName(), it2->first, it2->first.size()) == 0) { bInsert = false; break; } } } if (bInsert) { setCmdAndVars.insert(var->GetName()); } } } void CConsoleHelpGen::InsertConsoleCommands(std::set& setCmdAndVars, std::map mapPrefix) const { CXConsole::ConsoleCommandsMap::const_iterator itrCmd, itrCmdEnd = m_rParent.m_mapCommands.end(); for (itrCmd = m_rParent.m_mapCommands.begin(); itrCmd != itrCmdEnd; ++itrCmd) { const CConsoleCommand& cmd = itrCmd->second; bool bInsert = true; { std::map::const_iterator it2, end = mapPrefix.end(); for (it2 = mapPrefix.begin(); it2 != end; ++it2) { if (it2->first != "___" && _strnicmp(cmd.m_sName, it2->first, it2->first.size()) == 0) { bInsert = false; break; } } } if (bInsert) { setCmdAndVars.insert(cmd.m_sName.c_str()); } } } void CConsoleHelpGen::CreateSingleEntryFile(const char* szName) const { assert(m_eWorkMode == eWM_Confluence); // only needed for confluence FILE* f3 = nullptr; azfopen(&f3, (string(GetFolderName()) + GetFileExtension() + "/" + FixAnchorName(szName)).c_str(), "w"); if (!f3) { assert(0); return; // error } // StartPage(f3,szName,""); // HTML style IncludeSingleEntry(f3, szName); // EndPage(f3); // HTML style fclose(f3); } const CConsoleCommand* CConsoleHelpGen::FindConsoleCommand(const char* szName) const { CXConsole::ConsoleCommandsMap::const_iterator itrCmd, itrCmdEnd = m_rParent.m_mapCommands.end(); for (itrCmd = m_rParent.m_mapCommands.begin(); itrCmd != itrCmdEnd; ++itrCmd) { const CConsoleCommand& cmd = itrCmd->second; if (strcmp(cmd.m_sName.c_str(), szName) == 0) { return &cmd; } } return 0; } void CConsoleHelpGen::IncludeSingleEntry(FILE* f, const char* szName) const { StartCVar(f, szName); uint32 dwFlags = 0; const char* szHelp = ""; // slow but good for simpler code if (ICVar* pVar = gEnv->pConsole->GetCVar(szName)) { dwFlags = pVar->GetFlags(); szHelp = pVar->GetHelp(); } else if (const CConsoleCommand* pCommand = FindConsoleCommand(szName)) { dwFlags = pCommand->m_nFlags; szHelp = pCommand->m_sHelp.c_str(); } else { assert(0); // internal error } const char* szFlags = CXConsole::GetFlagsString(dwFlags); if (*szFlags) { // fprintf(f3,"%%GRAY%% %s %%ENDCOLOR%%
    \n",szFlags); // twiki style if (m_eWorkMode == eWM_HTML) { fprintf(f, "%s
    \n", szFlags); // simple HTML style } else if (m_eWorkMode == eWM_Confluence) { fprintf(f, "%s

    \n", szFlags); } else { assert(0); } } if (*szHelp == 0) { // fprintf(f,"%%TODO%%\n"); // wiki style, in our wiki %TODO% is defined as \"TODO\" if (m_eWorkMode == eWM_HTML) { fprintf(f, "
    *TODO*
    \n"); // HTML style } else if (m_eWorkMode == eWM_Confluence) { fprintf(f, "{warning}TODO{warning}\n"); // Confluence style } else { assert(0); } } else { if (m_eWorkMode == eWM_HTML) { fprintf(f, "
    \n%s\n
    \n", szHelp); // HTML style, to get fixed with font (layout in code is often making the assumption the forn is fixed width) } else if (m_eWorkMode == eWM_Confluence) { fprintf(f, "
    \n");
    
                string sHelp = szHelp;
    
                // currently not required as the {noformat} is used
                //          sHelp.replace("[","\\[");       sHelp.replace("]","\\]");
                //          sHelp.replace("{","\\{");       sHelp.replace("}","\\}");
                //          sHelp.replace("(","\\(");       sHelp.replace(")","\\)");
    
                fprintf(f, "%s\n", sHelp.c_str());       // Confluence style
    
                fprintf(f, "
    "); } else { assert(0); } } EndCVar(f); } void CConsoleHelpGen::Work() { // string sEngineFolder = string("@user@/")+GetFolderName(); // gEnv->pCryPak->RemoveDir(sEngineFolder.c_str()); // todo: check if that works // gEnv->pFileIO->CreatePath(sEngineFolder.c_str()); m_eWorkMode = eWM_HTML; CreateMainPages(); m_eWorkMode = eWM_Confluence; CreateMainPages(); CreateFileForEachEntry(); m_eWorkMode = eWM_None; } void CConsoleHelpGen::CreateFileForEachEntry() { assert(m_eWorkMode == eWM_Confluence); // only needed for confluence // generate a single file for each console command { CXConsole::ConsoleCommandsMap::const_iterator itrCmd, itrCmdEnd = m_rParent.m_mapCommands.end(); for (itrCmd = m_rParent.m_mapCommands.begin(); itrCmd != itrCmdEnd; ++itrCmd) { const CConsoleCommand& cmd = itrCmd->second; CreateSingleEntryFile(cmd.m_sName.c_str()); } } // generate a single file for each console variable { CXConsole::ConsoleVariablesMap::iterator itrVar, itrVarEnd = m_rParent.m_mapVariables.end(); for (itrVar = m_rParent.m_mapVariables.begin(); itrVar != itrVarEnd; ++itrVar) { ICVar* var = itrVar->second; CreateSingleEntryFile(var->GetName()); } } } void CConsoleHelpGen::CreateMainPages() { gEnv->pFileIO->CreatePath(GetFolderName()); std::map mapPrefix; // order here doesn't matter, after the name some help can be added (after the first return) mapPrefix[ "AI_"] = "Artificial Intelligence"; mapPrefix[ "NET_"] = "Network"; mapPrefix[ "ED_"] = "Editor"; mapPrefix[ "ES_"] = "Entity System"; mapPrefix[ "CON_"] = "Console"; mapPrefix[ "AG_"] = "Animation Graph" "\n" "High level animation logic, describes animation selection and flow, matches animation state to current game logical state."; mapPrefix[ "AC_"] = "Animated Character" "\n" "Better name would be 'Character Movement'.\nBridges game controlled movement and animation controlled movement."; mapPrefix[ "CA_"] = "Character Animation" "\n" "Motion synthesize and playback, parameterization through blending and inversed kinematics."; mapPrefix[ "E_"] = "3DEngine"; mapPrefix[ "I_"] = "Input"; mapPrefix[ "FG_"] = "Flow Graph" "\n" "hyper graph: game logic"; mapPrefix[ "P_"] = "Physics"; mapPrefix[ "R_"] = "Renderer"; mapPrefix[ "S_"] = "Sound"; mapPrefix[ "G_"] = "Game" "\n" "game specific, not part of CryEngine"; mapPrefix[ "SYS_"] = "System"; mapPrefix[ "V_"] = "Vehicle"; mapPrefix[ "FT_"] = "Feature Test"; mapPrefix[ "DEMO_"] = "Time Demo"; mapPrefix[ "FT_"] = "Feature Test"; mapPrefix[ "GL_"] = "Game Lobby"; mapPrefix[ "HUD_"] = "Heads Up Display"; mapPrefix[ "KC_"] = "Kill Cam"; mapPrefix[ "MN_"] = "Mannequin"; mapPrefix[ "PL_"] = "Player"; mapPrefix[ "PP_"] = "Player Progression"; mapPrefix[ "AIM_"] = "Aiming"; mapPrefix["CAPTURE_"] = "Capture"; mapPrefix[ "DS_"] = "Dialog Scripts"; mapPrefix[ "GT_"] = "Game Token"; mapPrefix[ "LOG_"] = "Logging"; mapPrefix[ "MOV_"] = "Movie Sequences"; mapPrefix[ "OSM_"] = "Overload Scene Manager"; mapPrefix["PROFILE_"] = "Profiling"; mapPrefix[ "STAP_"] = "Screen-space Torso Aim Pose"; mapPrefix[ "LUA_"] = "Lua" "\n" "scripting system"; mapPrefix[ "SV_"] = "Server"; mapPrefix[ "MFX_"] = "Material Effects"; mapPrefix[ "M_"] = "Multi threading"; mapPrefix[ "CC_"] = "Character Customization"; mapPrefix[ "CL_"] = "Client"; mapPrefix[ "Q_"] = "Quality" "\n" "usually shader quality"; mapPrefix[ "T_"] = "Timer"; mapPrefix[ "___"] = "Remaining"; // key defined to get it sorted in the end FILE* f1 = nullptr; azfopen(&f1, (string(GetFolderName()) + "/index" + GetFileExtension()).c_str(), "w"); if (!f1) { return; } StartPage(f1, "CryEngine ConsoleHTMLHelp", "main page"); StartH1(f1, "Console Commands and Variables"); LogVersion(f1); if (m_eWorkMode == eWM_HTML) { fprintf(f1, "This list was exported from the engine by using the DumpCommandsVars console command.
    \n\n"); } else if (m_eWorkMode == eWM_Confluence) { fprintf(f1, "This list was exported from the engine by using the *DumpCommandsVars* console command.\n\n"); } else { assert(0); } // show all registered Prefix with one line { std::map::const_iterator it, end = mapPrefix.end(); StartH3(f1, "Registered Prefixes"); for (it = mapPrefix.begin(); it != end; ++it) { const char* szLocalPrefix = it->first.c_str(); // can be 0 for remaining ones string sCleanPrefix = GetCleanPrefix(szLocalPrefix); string sPrefixName = SplitPrefixString_Part1(it->second); SingleLinePrefix(f1, sCleanPrefix.c_str(), sPrefixName.c_str(), (string("CONSOLEPREFIX") + FixAnchorName(sCleanPrefix.c_str()) + GetFileExtension()).c_str()); // fprintf(f1," * [[CONSOLEPREFIX%s][%s_ %s]]\n",FixAnchorName(sCleanPrefix.c_str()).c_str(),sCleanPrefix.c_str(),sPrefixName.c_str()); } EndH3(f1); // Registered prefixes } { std::map::const_iterator it, it2, end = mapPrefix.end(); StartH3(f1, "Console Commands and Variables Sorted by Prefix"); for (it = mapPrefix.begin(); it != end; ++it) { const char* szLocalPrefix = it->first.c_str(); // can be 0 for remaining ones string sCleanPrefix = GetCleanPrefix(szLocalPrefix); string sPrefixName = SplitPrefixString_Part1(it->second); std::set setCmdAndVars; // to get console variables and commands sorted together if (strcmp("___", szLocalPrefix) != 0) { // insert all starting with the prefix InsertConsoleVars(setCmdAndVars, szLocalPrefix); InsertConsoleCommands(setCmdAndVars, szLocalPrefix); } else { // insert all not starting with any of the prefix InsertConsoleVars(setCmdAndVars, mapPrefix); InsertConsoleCommands(setCmdAndVars, mapPrefix); } // ------------------------------- string sSubName = string("CONSOLEPREFIX") + sCleanPrefix; StartPrefix(f1, sCleanPrefix.c_str(), sPrefixName.c_str(), (sSubName + GetFileExtension()).c_str()); string sFileOut = string(GetFolderName()) + "/" + sSubName + GetFileExtension(); FILE* f2 = nullptr; azfopen(&f2, sFileOut.c_str(), "w"); if (!f2) { fclose(f1); return; } // headline { string sHeadline; if (sCleanPrefix.empty()) { sHeadline = "Console Commands and Variables Without Special Prefix"; } else { sHeadline = string("Console Commands and Variables with Prefix ") + sCleanPrefix + "_"; } StartH1(f2, sHeadline.c_str()); } Explanation(f2, SplitPrefixString_Part2(it->second)); KeyValue(f2, "Possible Flags", CXConsole::GetFlagsString(0xffffffff)); // fprintf(f2,"Possible Flags:
    \n"); // fprintf(f2,"
    %s
    ",CXConsole::GetFlagsString(0xffffffff)); // log console variables and commands { StartH3(f2, "Alphabetically Sorted"); std::set::const_iterator itI, endI = setCmdAndVars.end(); for (itI = setCmdAndVars.begin(); itI != endI; ++itI) { SingleLineEntry_InGlobal(f1, *itI, (sSubName + GetFileExtension() + "#Anchor" + FixAnchorName(*itI)).c_str()); SingleLineEntry_InGroup(f2, *itI, (string("#Anchor") + FixAnchorName(*itI)).c_str()); } EndH3(f2); } { StartH3(f2, "Console Variables and Commands"); bool bFirst = true; { std::set::const_iterator itI, endI = setCmdAndVars.end(); for (itI = setCmdAndVars.begin(); itI != endI; ++itI) { if (!bFirst) { Separator(f2); } bFirst = false; Anchor(f2, (string("Anchor") + FixAnchorName(*itI)).c_str()); // anchor IncludeSingleEntry(f2, *itI); } } EndH3(f2); } EndH1(f2); // Console Commands and Variables ... fclose(f2); f2 = 0; EndPrefix(f1); } EndH3(f1); // Console commands and variables sorted by prefix } EndH1(f1); EndPage(f1); fclose(f1); m_rParent.ConsoleLogInputResponse("successfully wrote directory %s", GetFolderName()); } void CConsoleHelpGen::Separator(FILE* f) const { if (m_eWorkMode == eWM_HTML) { fprintf(f, "
    \n"); } else if (m_eWorkMode == eWM_Confluence) { // fprintf(f,"----\n"); } else { assert(0); } } void CConsoleHelpGen::Explanation(FILE* f, const char* szText) const { if (m_eWorkMode == eWM_HTML) { fprintf(f, "
    %s

    \n
    \n", szText); } else if (m_eWorkMode == eWM_Confluence) { // fprintf(f,"{quote}%s{quote}\n\n",szText); fprintf(f, "%s\n\n", szText); } else { assert(0); } } const char* CConsoleHelpGen::GetFileExtension() const { if (m_eWorkMode == eWM_HTML) { return ".html"; } else if (m_eWorkMode == eWM_Confluence) { } else { assert(0); } return ""; } const char* CConsoleHelpGen::GetFolderName() const { if (m_eWorkMode == eWM_HTML) { return "ConsoleHTMLHelp"; } else if (m_eWorkMode == eWM_Confluence) { return "ConsoleHTMLHelp/CRYAUTOGEN"; } else { assert(0); } return 0; } #endif // defined(WIN32) || defined(WIN64)