guihandler.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 2,423 行 · 第 1/5 页
CPP
2,423 行
#include "StdAfx.h"
// GuiHandler.cpp: implementation of the CGuiHandler class.
//
//////////////////////////////////////////////////////////////////////
#include "GuiHandler.h"
#include <map>
#include <set>
#include <list>
#include "SDL_keysym.h"
#include "SDL_mouse.h"
#include "CommandColors.h"
#include "KeyBindings.h"
#include "KeyCodes.h"
#include "LuaUI.h"
#include "MiniMap.h"
#include "MouseHandler.h"
#include "OutlineFont.h"
#include "Game/Camera.h"
#include "Game/Game.h"
#include "Game/GameHelper.h"
#include "Game/SelectedUnits.h"
#include "Map/BaseGroundDrawer.h"
#include "Map/Ground.h"
#include "Rendering/glFont.h"
#include "Rendering/GL/glExtra.h"
#include "Rendering/GL/glList.h"
#include "Rendering/GL/myGL.h"
#include "Rendering/Textures/Bitmap.h"
#include "Rendering/Textures/NamedTextures.h"
#include "Rendering/Textures/TextureHandler.h"
#include "Rendering/UnitModels/3DOParser.h"
#include "Rendering/UnitModels/UnitDrawer.h"
#include "Sim/Misc/Feature.h"
#include "Sim/Misc/LosHandler.h"
#include "Sim/Units/CommandAI/CommandAI.h"
#include "Sim/Units/CommandAI/BuilderCAI.h"
#include "Sim/Units/UnitDefHandler.h"
#include "Sim/Units/Unit.h"
#include "Sim/Units/UnitHandler.h"
#include "Sim/Units/UnitLoader.h"
#include "Sim/Weapons/WeaponDefHandler.h"
#include "Sim/Weapons/Weapon.h"
#include "System/FileSystem/SimpleParser.h"
#include "System/LogOutput.h"
#include "System/Platform/ConfigHandler.h"
#include "mmgr.h"
extern Uint8 *keys;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CGuiHandler* guihandler = NULL;
const char* CGuiHandler::luaUiFile = "gui.lua";
CGuiHandler::CGuiHandler()
: firstLayout(true),
inCommand(-1),
activeMousePress(false),
forceLayoutUpdate(false),
defaultCmdMemory(-1),
needShift(false),
maxPage(0),
activePage(0),
showingMetal(false),
buildSpacing(0),
buildFacing(0),
actionOffset(0),
luaUIClick(false),
gatherMode(false)
{
icons = SAFE_NEW IconInfo[16];
iconsSize = 16;
iconsCount = 0;
LoadConfig("ctrlpanel.txt");
miniMapMarker = !!configHandler.GetInt("MiniMapMarker", 1);
invertQueueKey = !!configHandler.GetInt("InvertQueueKey", 0);
readmap->mapDefParser.GetDef(autoShowMetal, "1", "MAP\\autoShowMetal");
useStencil = false;
if (GLEW_NV_depth_clamp && !!configHandler.GetInt("StencilBufferBits", 1)) {
GLint stencilBits;
glGetIntegerv(GL_STENCIL_BITS, &stencilBits);
useStencil = (stencilBits >= 1);
}
}
CGuiHandler::~CGuiHandler()
{
CLuaUI::FreeHandler();
delete[] icons;
std::map<std::string, unsigned int>::iterator it;
for (it = textureMap.begin(); it != textureMap.end(); ++it) {
const GLuint texID = it->second;
glDeleteTextures (1, &texID);
}
}
bool CGuiHandler::GetQueueKeystate() const
{
return (!invertQueueKey && keys[SDLK_LSHIFT]) ||
(invertQueueKey && !keys[SDLK_LSHIFT]);
}
void CGuiHandler::LoadDefaults()
{
xIcons = 2;
yIcons = 8;
xPos = 0.000f;
yPos = 0.175f;
xIconSize = 0.060f;
yIconSize = 0.060f;
textBorder = 0.003f;
iconBorder = 0.003f;
frameBorder = 0.003f;
xSelectionPos = 0.018f;
ySelectionPos = 0.127f;
frameAlpha = -1.0f;
textureAlpha = 0.8f;
dropShadows = true;
useOptionLEDs = true;
selectGaps = true;
selectThrough = false;
menuName = "";
outlineFont.Enable(false);
attackRect = true;
newAttackMode = true;
invColorSelect = true;
frontByEnds = false;
}
static bool SafeAtoF(float& var, const string& value)
{
char* endPtr;
const char* startPtr = value.c_str();
const float tmp = (float)strtod(startPtr, &endPtr);
if (endPtr == startPtr) {
return false;
}
var = tmp;
return true;
}
bool CGuiHandler::LoadConfig(const std::string& filename)
{
LoadDefaults();
CFileHandler ifs(filename);
CSimpleParser parser(ifs);
string deadStr = "";
string prevStr = "";
string nextStr = "";
string fillOrderStr = "";
while (true) {
const string line = parser.GetCleanLine();
if (line.empty()) {
break;
}
vector<string> words = parser.Tokenize(line, 1);
const string command = StringToLower(words[0]);
if ((command == "dropshadows") && (words.size() > 1)) {
dropShadows = !!atoi(words[1].c_str());
}
else if ((command == "useoptionleds") && (words.size() > 1)) {
useOptionLEDs = !!atoi(words[1].c_str());
}
else if ((command == "selectgaps") && (words.size() > 1)) {
selectGaps = !!atoi(words[1].c_str());
}
else if ((command == "selectthrough") && (words.size() > 1)) {
selectThrough = !!atoi(words[1].c_str());
}
else if ((command == "deadiconslot") && (words.size() > 1)) {
deadStr = StringToLower(words[1]);
}
else if ((command == "prevpageslot") && (words.size() > 1)) {
prevStr = StringToLower(words[1]);
}
else if ((command == "nextpageslot") && (words.size() > 1)) {
nextStr = StringToLower(words[1]);
}
else if ((command == "fillorder") && (words.size() > 1)) {
fillOrderStr = StringToLower(words[1]);
}
else if ((command == "xicons") && (words.size() > 1)) {
xIcons = atoi(words[1].c_str());
}
else if ((command == "yicons") && (words.size() > 1)) {
yIcons = atoi(words[1].c_str());
}
else if ((command == "xiconsize") && (words.size() > 1)) {
SafeAtoF(xIconSize, words[1]);
}
else if ((command == "yiconsize") && (words.size() > 1)) {
SafeAtoF(yIconSize, words[1]);
}
else if ((command == "xpos") && (words.size() > 1)) {
SafeAtoF(xPos, words[1]);
}
else if ((command == "ypos") && (words.size() > 1)) {
SafeAtoF(yPos, words[1]);
}
else if ((command == "textborder") && (words.size() > 1)) {
SafeAtoF(textBorder, words[1]);
}
else if ((command == "iconborder") && (words.size() > 1)) {
SafeAtoF(iconBorder, words[1]);
}
else if ((command == "frameborder") && (words.size() > 1)) {
SafeAtoF(frameBorder, words[1]);
}
else if ((command == "xselectionpos") && (words.size() > 1)) {
SafeAtoF(xSelectionPos, words[1]);
}
else if ((command == "yselectionpos") && (words.size() > 1)) {
SafeAtoF(ySelectionPos, words[1]);
}
else if ((command == "framealpha") && (words.size() > 1)) {
SafeAtoF(frameAlpha, words[1]);
}
else if ((command == "texturealpha") && (words.size() > 1)) {
SafeAtoF(textureAlpha, words[1]);
}
else if ((command == "outlinefont") && (words.size() > 1)) {
outlineFont.Enable(!!atoi(words[1].c_str()));
}
else if ((command == "attackrect") && (words.size() > 1)) {
attackRect = !!atoi(words[1].c_str());
}
else if ((command == "newattackmode") && (words.size() > 1)) {
newAttackMode = !!atoi(words[1].c_str());
}
else if ((command == "invcolorselect") && (words.size() > 1)) {
invColorSelect = !!atoi(words[1].c_str());
}
else if ((command == "frontbyends") && (words.size() > 1)) {
frontByEnds = !!atoi(words[1].c_str());
}
}
// sane clamps
xIcons = max(2, xIcons);
yIcons = max(2, yIcons);
xIconSize = max(0.010f, xIconSize);
yIconSize = max(0.010f, yIconSize);
iconBorder = max(0.0f, iconBorder);
frameBorder = max(0.0f, frameBorder);
xIconStep = xIconSize + (iconBorder * 2.0f);
yIconStep = yIconSize + (iconBorder * 2.0f);
iconsPerPage = (xIcons * yIcons);
buttonBox.x1 = xPos;
buttonBox.x2 = xPos + (frameBorder * 2.0f) + (xIcons * xIconStep);
buttonBox.y1 = yPos;
buttonBox.y2 = yPos + (frameBorder * 2.0f) + (yIcons * yIconStep);
if (!deadStr.empty()) {
deadIconSlot = ParseIconSlot(deadStr);
} else {
deadIconSlot = -1;
}
if (!prevStr.empty() && (prevStr != "auto")) {
if (prevStr == "none") {
prevPageSlot = -1;
} else {
prevPageSlot = ParseIconSlot(prevStr);
}
} else {
prevPageSlot = iconsPerPage - 2;
}
if (!nextStr.empty() && (nextStr != "auto")) {
if (nextStr == "none") {
nextPageSlot = -1;
} else {
nextPageSlot = ParseIconSlot(nextStr);
}
} else {
nextPageSlot = iconsPerPage - 1;
}
if (deadIconSlot >= 0) {
const float fullBorder = frameBorder + iconBorder;
const float fx = (float)(deadIconSlot % xIcons);
const float fy = (float)(deadIconSlot / xIcons);
xBpos = buttonBox.x1 + (fullBorder + (0.5 * xIconSize) + (fx * xIconStep));
yBpos = buttonBox.y2 - (fullBorder + (0.5 * yIconSize) + (fy * yIconStep));
}
else if ((prevPageSlot >= 0) && (nextPageSlot >= 0)) {
// place in the middle of adjacent paging icons
const int delta = abs(prevPageSlot - nextPageSlot);
if ((delta == 1) || (delta == xIcons)) {
const float fullBorder = frameBorder + iconBorder;
const float fxp = (float)(prevPageSlot % xIcons);
const float fyp = (float)(prevPageSlot / xIcons);
const float fxn = (float)(nextPageSlot % xIcons);
const float fyn = (float)(nextPageSlot / xIcons);
const float fx = 0.5f * (fxp + fxn);
const float fy = 0.5f * (fyp + fyn);
xBpos = buttonBox.x1 + (fullBorder + (0.5 * xIconSize) + (fx * xIconStep));
yBpos = buttonBox.y2 - (fullBorder + (0.5 * yIconSize) + (fy * yIconStep));
}
else {
xBpos = yBpos = -1.0f; // off screen
}
}
else {
xBpos = yBpos = -1.0f; // off screen
}
ParseFillOrder(fillOrderStr);
return true;
}
void CGuiHandler::ParseFillOrder(const std::string& text)
{
// setup the default order
fillOrder.clear();
for (int i = 0; i < iconsPerPage; i++) {
fillOrder.push_back(i);
}
// split the string into slot names
std::vector<std::string> slotNames = CSimpleParser::Tokenize(text, 0);
if ((int)slotNames.size() != iconsPerPage) {
return;
}
std::set<int> slotSet;
std::vector<int> slotVec;
for (int s = 0; s < iconsPerPage; s++) {
const int slotNumber = ParseIconSlot(slotNames[s]);
if ((slotNumber < 0) || (slotNumber >= iconsPerPage) ||
(slotSet.find(slotNumber) != slotSet.end())) {
return;
}
slotSet.insert(slotNumber);
slotVec.push_back(slotNumber);
}
fillOrder = slotVec;
}
int CGuiHandler::ParseIconSlot(const std::string& text) const
{
const char rowLetter = tolower(text[0]);
if ((rowLetter < 'a') || (rowLetter > 'z')) {
return -1;
}
const int row = rowLetter - 'a';
if (row >= yIcons) {
return -1;
}
char* endPtr;
const char* startPtr = text.c_str() + 1;
int column = strtol(startPtr, &endPtr, 10);
if ((endPtr == startPtr) || (column < 0) || (column >= xIcons)) {
return -1;
}
return (row * xIcons) + column;
}
bool CGuiHandler::ReloadConfig(const string& filename)
{
LoadConfig(filename);
activePage = 0;
selectedUnits.SetCommandPage(activePage);
LayoutIcons(false);
return true;
}
void CGuiHandler::ResizeIconArray(unsigned int size)
{
int minIconsSize = iconsSize;
while (minIconsSize < size) {
minIconsSize *= 2;
}
if (iconsSize < minIconsSize) {
iconsSize = minIconsSize;
delete[] icons;
icons = SAFE_NEW IconInfo[iconsSize];
}
}
void CGuiHandler::AppendPrevAndNext(vector<CommandDescription>& cmds)
{
CommandDescription cd;
cd.id=CMD_INTERNAL;
cd.action="prevmenu";
cd.type=CMDTYPE_PREV;
cd.name="";
cd.tooltip = "Previous menu";
cmds.push_back(cd);
cd.id=CMD_INTERNAL;
cd.action="nextmenu";
cd.type=CMDTYPE_NEXT;
cd.name="";
cd.tooltip = "Next menu";
cmds.push_back(cd);
}
int CGuiHandler::FindInCommandPage()
{
if ((inCommand < 0) || (inCommand >= commands.size())) {
return -1;
}
for (int ii = 0; ii < iconsCount; ii++) {
const IconInfo& icon = icons[ii];
if (icon.commandsID == inCommand) {
return (ii / iconsPerPage);
}
}
return -1;
}
void CGuiHandler::RevertToCmdDesc(const CommandDescription& cmdDesc,
bool defaultCommand, bool samePage)
{
for (int a = 0; a < commands.size(); ++a) {
if (commands[a].id == cmdDesc.id) {
if (defaultCommand) {
defaultCmdMemory = a;
return;
}
inCommand = a;
if (commands[a].type == CMDTYPE_ICON_BUILDING) {
const UnitDef* ud = unitDefHandler->GetUnitByID(-commands[a].id);
SetShowingMetal(ud->extractsMetal > 0);
} else {
SetShowingMetal(false);
}
if (samePage) {
for (int ii = 0; ii < iconsCount; ii++) {
if (inCommand == icons[ii].commandsID) {
activePage = min(maxPage, (ii / iconsPerPage));;
selectedUnits.SetCommandPage(activePage);
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?