#include "hud.h" #include "cl_util.h" #include "vgui_TeamFortressViewport.h" #include "vgui_paranoiatext.h" #include "VGUI_LineBorder.h" #include "VGUI_TextImage.h" #include "../engine/keydefs.h" #include "triangleapi.h" #include "../game_shared/vgui_loadtga.h" #include "r_studioint.h" #include "com_model.h" #include "stringlib.h" #include "gl_local.h" extern engine_studio_api_t IEngineStudio; #define WSIZE_X XRES(400); #define WSIZE_Y YRES(400); // возвращает 1, если тэг существует, и 0 в случае конца файла // ptext останавливается на открывающей скобке тэга int FindNextTag(char* &ptext) { while (*ptext != '<') { if (*ptext == 0) return 0; // end of file ptext++; } // теперь надо убедиться, что тэг имеет закрывающую скобку char* hlp = ptext; while (*hlp != '>') { if (*hlp == 0) return 0; hlp++; } return 1; } // получает указатель на начало названия тэга, и доходит либо до пробела, либо // до закрывающей скобки // размер буфера - 32 символа // возвращает 1, если у тэга есть параметры, и 0 - если нету int GetTagName(char* &ptext, char* bufTagName) { char* pstart = ptext; while(1) { if (*ptext == '>') { int length = ptext - pstart; if (length > 31) length = 31; memcpy(bufTagName, pstart, length); bufTagName[length] = 0; ptext++; return 0; } else if (*ptext == ' ') { int length = ptext - pstart; if (length > 31) length = 31; memcpy(bufTagName, pstart, length); bufTagName[length] = 0; return 1; } ptext++; } } // получает указатель на место сразу за именем тэга, и возвращает его параметры в буферах // буферы должны быть размером в 32 байта // предполагает, что конец файла наступить не должен до закрывающей скобки int GetTagParameter(char* &ptext, char* bufParamName, char* bufParamValue) { // пропускаем начальные пробелы и переносы while (*ptext == ' ' || *ptext == '\n') ptext++; // начинаем чтение названия параметра char* start = ptext; while (*ptext != '=') { if (*ptext == '>') { ptext++; return 0; // тэг кончился } ptext++; } int paramNameLength = ptext - start; if (paramNameLength > 31) paramNameLength = 31; // обрезать по буферу memcpy(bufParamName, start, paramNameLength); bufParamName[paramNameLength] = 0; // теперь читаем его значение ptext++; // перепрыгиваем знак равно if (*ptext == '\"') { // аргумент заключен в кавычки ptext++; start = ptext; while (1) { if (*ptext == '\"') { int paramValueLength = ptext - start; if (paramValueLength > 31) paramValueLength = 31; memcpy(bufParamValue, start, paramValueLength); bufParamValue[paramValueLength] = 0; ptext++; return 1; } else if (*ptext == '>') { int paramValueLength = ptext - start; if (paramValueLength > 31) paramValueLength = 31; memcpy(bufParamValue, start, paramValueLength); bufParamValue[paramValueLength] = 0; return 1; } ptext++; } } start = ptext; while(1) { if (*ptext == '>' || *ptext == ' ' || *ptext == '\n') { int paramValueLength = ptext - start; if (paramValueLength > 31) paramValueLength = 31; memcpy(bufParamValue, start, paramValueLength); bufParamValue[paramValueLength] = 0; return 1; } ptext++; } } void ParseColor(char* ptext, int &r, int &g, int &b, int &a) { int iArray[4]; int current = 0; char tmp[8]; memset(iArray, 0, sizeof(int)*4); while (current < 4 && *ptext != 0) { // search for space or end of string char* pstart = ptext; while (*ptext != ' ' && *ptext != 0) ptext++; int length = ptext - pstart; if (length > 7) length = 7; memcpy(tmp, pstart, length); tmp[length] = 0; iArray[current] = atoi(tmp); current++; if (*ptext == ' ') ptext++; } r = iArray[0]; g = iArray[1]; b = iArray[2]; a = iArray[3]; } // ===================================================================== /*class CMainPanel : public Panel, public CRenderable { public: CMainPanel(const char* imgname, int x,int y,int wide,int tall) : Panel(x, y, wide, tall) { m_pBitmap = vgui_LoadTGA(imgname); setPaintBackgroundEnabled(false); if (!m_pBitmap) gEngfuncs.Con_Printf("Cant load image for background: [%s]\n", imgname); m_pBorderPanel = NULL; } ~CMainPanel() { if (m_pBitmap) delete m_pBitmap; } void paint() { if (m_pBitmap) { int imgX, imgY; int panX, panY; m_pBitmap->getSize(imgX, imgY); getSize(panX, panY); for (int curY = 0; curY < panY; curY += imgY) { for (int curX = 0; curX < panX; curX += imgX) { m_pBitmap->setPos(curX, curY); m_pBitmap->doPaint(this); } } } else { drawSetColor(0, 0, 0, 100); drawFilledRect(0, 0, getWide(), getTall()); } drawSetColor(0, 0, 0, 150); drawOutlinedRect(0, 0, getWide() - 1, getTall() - 1); drawSetColor(255, 255, 255, 150); drawOutlinedRect(1, 1, getWide(), getTall()); drawSetColor(0, 0, 0, 0); drawOutlinedRect(0, 0, getWide(), getTall()); // sort of hack, to draw frame around the scrollpanel if (m_pBorderPanel) { int x, y, wide, tall; m_pBorderPanel->getBounds(x, y, wide, tall); drawSetColor(255, 255, 255, 180); drawOutlinedRect(x-2, y-2, x+wide+1, y+tall+1); drawSetColor(0, 0, 0, 60); drawOutlinedRect(x-1, y-1, x+wide+2, y+tall+2); drawSetColor(0, 0, 0, 0); drawOutlinedRect(x-2, y-2, x+wide+2, y+tall+2); } } void SetDrawBorder(Panel *pan) { m_pBorderPanel = pan; } private: BitmapTGA* m_pBitmap; Panel* m_pBorderPanel; }; class CMyButton : public Button, public CRenderable { public: CMyButton(const char* text, const char* imgname, int x, int y) : Button(text, x, y) { m_pBitmap = vgui_LoadTGA(imgname); if (m_pBitmap) m_pBitmap->setPos(0,0); else gEngfuncs.Con_Printf("Cant load image for button: [%s]\n", imgname); } ~CMyButton() { if (m_pBitmap) delete m_pBitmap; } void paintBackground() { if (m_pBitmap) m_pBitmap->doPaint(this); if (isSelected()) { drawSetColor(0, 0, 0, 200); drawFilledRect(0, 0, getWide(), getTall()); drawSetColor(255, 255, 255, 150); drawOutlinedRect(0, 0, getWide()-1, getTall()-1); drawSetColor(0, 0, 0, 150); drawOutlinedRect(1, 1, getWide(), getTall()); } else { drawSetColor(0, 0, 0, 150); drawOutlinedRect(0, 0, getWide()-1, getTall()-1); drawSetColor(255, 255, 255, 150); drawOutlinedRect(1, 1, getWide(), getTall()); } drawSetColor(0, 0, 0, 0); drawOutlinedRect(0, 0, getWide(), getTall()); } void internalCursorExited() { setSelected(false); } private: BitmapTGA* m_pBitmap; };*/ void OrthoQuad(int x1, int y1, int x2, int y2); //================================== // CMainPanel - главная панель окна. //================================== class CMainPanel : public Panel, public CRenderable { public: CMainPanel(const char* imgname, int x,int y,int wide,int tall) : Panel(x, y, wide, tall) { setPaintBackgroundEnabled(false); if (!IEngineStudio.IsHardware() || imgname[0] == 0) { setPaintEnabled(true); m_hsprImage = NULL; m_hBitmap = 0; return; } else setPaintEnabled(false); const char *ext = UTIL_FileExtension( imgname ); m_hBitmap = 0; if(( !Q_stricmp( ext, "dds" ) || !Q_stricmp( ext, "tga" )) && g_fRenderInterfaceValid ) { m_hBitmap = LOAD_TEXTURE( imgname, NULL, 0, TF_IMAGE ); if (!m_hBitmap) { gEngfuncs.Con_Printf("ERROR: Cant load image for background: [%s]\n", imgname); setPaintEnabled(true); } return; } m_hsprImage = SPR_Load(imgname); if (!m_hsprImage) { gEngfuncs.Con_Printf("ERROR: Cant load image for background: [%s]\n", imgname); setPaintEnabled(true); return; } if (SPR_Frames(m_hsprImage) != 4) { gEngfuncs.Con_Printf("ERROR: Expecting 4 frames in sprite: [%s]\n", imgname); m_hsprImage = 0; setPaintEnabled(true); } } void Render() { int x, y; getPos(x, y); if( m_hBitmap && g_fRenderInterfaceValid ) { gEngfuncs.pTriAPI->RenderMode( kRenderTransAlpha ); GL_BindTexture( GL_TEXTURE0, m_hBitmap ); OrthoQuad( x, y, x + getWide(), y + getTall() ); gEngfuncs.pTriAPI->RenderMode(kRenderNormal); return; } if (!m_hsprImage) return; const struct model_s *sprmodel = gEngfuncs.GetSpritePointer(m_hsprImage); gEngfuncs.pTriAPI->RenderMode(kRenderNormal); gEngfuncs.pTriAPI->SpriteTexture( (struct model_s *) sprmodel, 0); gEngfuncs.pTriAPI->CullFace( TRI_NONE ); //no culling gEngfuncs.pTriAPI->Color4f( 1, 1, 1, 1 ); OrthoQuad(x, y, x+getWide()/2, y+getTall()/2); gEngfuncs.pTriAPI->SpriteTexture( (struct model_s *) sprmodel, 1); gEngfuncs.pTriAPI->CullFace( TRI_NONE ); //no culling gEngfuncs.pTriAPI->Color4f( 1, 1, 1, 1 ); OrthoQuad(x+getWide()/2, y, x+getWide(), y+getTall()/2); gEngfuncs.pTriAPI->SpriteTexture( (struct model_s *) sprmodel, 2); gEngfuncs.pTriAPI->CullFace( TRI_NONE ); //no culling gEngfuncs.pTriAPI->Color4f( 1, 1, 1, 1 ); OrthoQuad(x, y+getTall()/2, x+getWide()/2, y+getTall()); gEngfuncs.pTriAPI->SpriteTexture( (struct model_s *) sprmodel, 3); gEngfuncs.pTriAPI->CullFace( TRI_NONE ); //no culling gEngfuncs.pTriAPI->Color4f( 1, 1, 1, 1 ); OrthoQuad(x+getWide()/2, y+getTall()/2, x+getWide(), y+getTall()); gEngfuncs.pTriAPI->CullFace( TRI_FRONT ); } // in case we didnt loaded texture.. void paint() { drawSetColor(0, 0, 0, 100); drawFilledRect(0, 0, getWide(), getTall()); drawSetColor(255, 255, 2550, 150); drawOutlinedRect(0, 0, getWide(), getTall()); if (m_pBorderPanel) { int x, y, wide, tall; m_pBorderPanel->getBounds(x, y, wide, tall); drawSetColor(255, 255, 255, 180); drawOutlinedRect(x-2, y-2, x+wide+1, y+tall+1); drawSetColor(0, 0, 0, 60); drawOutlinedRect(x-1, y-1, x+wide+2, y+tall+2); drawSetColor(0, 0, 0, 0); drawOutlinedRect(x-2, y-2, x+wide+2, y+tall+2); } } void SetDrawBorder(Panel *pan) { m_pBorderPanel = pan; } bool IsTgaPanel( void ) { return (m_hBitmap != 0) ? true : false; } private: HSPRITE m_hsprImage; int m_hBitmap; Panel* m_pBorderPanel; }; //================================== // CMyButton - кнопка закрытия окна //================================== class CMyButton : public Button, public CRenderable { public: CMyButton(const char* text, const char* imgname, int x, int y) : Button(text, x, y) { if (!IEngineStudio.IsHardware() || imgname[0] == 0) { setPaintBackgroundEnabled(true); m_hsprImage = NULL; return; } else setPaintBackgroundEnabled(false); m_hsprImage = SPR_Load(imgname); if (!m_hsprImage) { gEngfuncs.Con_Printf("ERROR: Cant load image for button: [%s]\n", imgname); setPaintBackgroundEnabled(true); return; } if (SPR_Frames(m_hsprImage) != 2) { gEngfuncs.Con_Printf("ERROR: Expecting 2 frames in sprite: [%s]\n", imgname); m_hsprImage = 0; setPaintBackgroundEnabled(true); } } void Render() { if (!m_hsprImage) return; int x, y, xparent, yparent; getPos(x, y); getParent()->getPos(xparent, yparent); x += xparent; y += yparent; int frame = 0; if (isSelected()) frame = 1; const struct model_s *sprmodel = gEngfuncs.GetSpritePointer(m_hsprImage); gEngfuncs.pTriAPI->RenderMode(kRenderNormal); gEngfuncs.pTriAPI->SpriteTexture( (struct model_s *) sprmodel, frame); gEngfuncs.pTriAPI->CullFace( TRI_NONE ); //no culling gEngfuncs.pTriAPI->Color4f( 1, 1, 1, 1 ); OrthoQuad(x, y, x+getWide(), y+getTall()); gEngfuncs.pTriAPI->CullFace( TRI_FRONT ); } void paintBackground() { if (isSelected()) { drawSetColor(58, 37, 19, 0); drawFilledRect(0, 0, getWide(), getTall()); drawSetColor(255, 255, 255, 150); drawOutlinedRect(0, 0, getWide()-1, getTall()-1); drawSetColor(0, 0, 0, 150); drawOutlinedRect(1, 1, getWide(), getTall()); } else { drawSetColor(98, 60, 30, 0); drawFilledRect(0, 0, getWide(), getTall()); drawSetColor(0, 0, 0, 150); drawOutlinedRect(0, 0, getWide()-1, getTall()-1); drawSetColor(255, 255, 255, 150); drawOutlinedRect(1, 1, getWide(), getTall()); } drawSetColor(0, 0, 0, 0); drawOutlinedRect(0, 0, getWide(), getTall()); } void internalCursorExited() { setSelected(false); } private: HSPRITE m_hsprImage; }; //================================== // CMySlider - ползунок прокрутки в стиле паранойи //================================== class CMySlider : public Slider { public: CMySlider(int x,int y,int wide,int tall,bool vertical) : Slider(x,y,wide,tall,vertical){}; void paintBackground( void ) { int wide,tall,nobx,noby; getPaintSize(wide,tall); getNobPos(nobx,noby); //background drawSetColor(98, 60, 30, 150); drawFilledRect( 0,0,wide,tall ); // nob drawSetColor(98, 60, 30, 0); drawFilledRect( 0,nobx,wide,noby ); drawSetColor(0, 0, 0, 150); drawOutlinedRect( 0,nobx,wide-1,noby-1 ); drawSetColor(255, 255, 255, 150); drawOutlinedRect( 1,nobx+1,wide,noby ); drawSetColor(0, 0, 0, 0); drawOutlinedRect( 0,nobx,wide,noby ); } }; //================================== // CMyScrollButton - кнопка прокрутки //================================== class CMyScrollbutton : public Button { public: CMyScrollbutton(int up, int x, int y) : Button("", x, y, 16, 16) { if (up) setImage(vgui_LoadTGA("gfx/vgui/arrowup.tga")); else setImage(vgui_LoadTGA("gfx/vgui/arrowdown.tga")); setPaintEnabled(true); setPaintBackgroundEnabled(true); } void paintBackground() { if (isSelected()) { drawSetColor(58, 37, 19, 0); drawFilledRect(0, 0, getWide(), getTall()); drawSetColor(255, 255, 255, 150); drawOutlinedRect(0, 0, getWide()-1, getTall()-1); drawSetColor(0, 0, 0, 150); drawOutlinedRect(1, 1, getWide(), getTall()); } else { drawSetColor(98, 60, 30, 0); drawFilledRect(0, 0, getWide(), getTall()); drawSetColor(0, 0, 0, 150); drawOutlinedRect(0, 0, getWide()-1, getTall()-1); drawSetColor(255, 255, 255, 150); drawOutlinedRect(1, 1, getWide(), getTall()); } drawSetColor(0, 0, 0, 0); drawOutlinedRect(0, 0, getWide(), getTall()); } void internalCursorExited() { setSelected(false); } }; //================================== // CMyScrollPanel - прокручиваемая панель //================================== class CMyScrollPanel : public ScrollPanel, public CRenderable { public: CMyScrollPanel(const char* imgname, int x,int y,int wide,int tall) : ScrollPanel(x, y, wide, tall) { ScrollBar *pScrollBar = getVerticalScrollBar(); pScrollBar->setButton( new CMyScrollbutton( 1, 0,0 ), 0 ); pScrollBar->setButton( new CMyScrollbutton( 0, 0,0 ), 1 ); pScrollBar->setSlider( new CMySlider(0,wide-1,wide,(tall-(wide*2))+2,true) ); pScrollBar->setPaintBorderEnabled(false); pScrollBar->setPaintBackgroundEnabled(false); pScrollBar->setPaintEnabled(false); setPaintBackgroundEnabled(false); setPaintEnabled(false); if (!IEngineStudio.IsHardware() || imgname[0] == 0) { m_hsprImage = NULL; // setPaintBackgroundEnabled(true); return; } m_hsprImage = SPR_Load(imgname); if (!m_hsprImage) { gEngfuncs.Con_Printf("ERROR: Cant load image for scrollpanel: [%s]\n", imgname); } } void Render() { if (!m_hsprImage) return; int x, y, xparent, yparent; getPos(x, y); getParent()->getPos(xparent, yparent); x += xparent; y += yparent; const struct model_s *sprmodel = gEngfuncs.GetSpritePointer(m_hsprImage); gEngfuncs.pTriAPI->RenderMode(kRenderNormal); gEngfuncs.pTriAPI->SpriteTexture( (struct model_s *) sprmodel, 0); gEngfuncs.pTriAPI->CullFace( TRI_NONE ); //no culling gEngfuncs.pTriAPI->Color4f( 1, 1, 1, 1 ); OrthoQuad(x, y, x+getWide(), y+getTall()); gEngfuncs.pTriAPI->CullFace( TRI_FRONT ); } /* void paint() { drawSetColor(255, 255, 255, 180); drawOutlinedRect(0, 0, getWide(), getTall()); }*/ private: HSPRITE m_hsprImage; }; // ============================================================== void CParanoiaTextPanel::BuildErrorPanel(const char* errorString) { CSchemeManager *pSchemes = gViewPort->GetSchemeManager(); SchemeHandle_t hTextScheme = pSchemes->getSchemeHandle( "Default Text" ); Font *pNormalFont = pSchemes->getFont( hTextScheme ); Panel* panel = new Panel(XRES(120), YRES(180), XRES(400), YRES(120)); panel->setParent(this); panel->setBgColor(0, 0, 0, 100); panel->setBorder(new LineBorder); int butX, butY; Button* button = new Button(" OK ", 0, 0); button->setParent(panel); button->addActionSignal(this); button->getSize(butX, butY); butX = (panel->getWide() - butX) / 2; butY = panel->getTall() - butY - YRES(10); button->setPos( butX, butY ); int labelpos = (butY - (pNormalFont->getTall() + YRES(8))) / 2; Label* label = new Label("", XRES(10), labelpos, panel->getWide() - XRES(20), pNormalFont->getTall() + YRES(8)); label->setParent(panel); label->setFont(pNormalFont); label->setPaintBackgroundEnabled(false); label->setFgColor(255, 255, 255, 0); label->setContentAlignment( Label::a_center ); label->setText( errorString ); return; } CParanoiaTextPanel::CParanoiaTextPanel(char* filename) : Panel(0, 0, ScreenWidth, ScreenHeight) { strcpy(m_loadedFileName, filename); // remember file name m_iRenderElms = 0; panel = NULL; setVisible(true); setPaintBackgroundEnabled(false); gViewPort->UpdateCursorState(); int fileLength; char* pFile = (char*)gEngfuncs.COM_LoadFile( filename, 5, &fileLength ); if (!pFile) { char buf[128]; sprintf(buf, "Unable to load file %s", filename); BuildErrorPanel(buf); return; } char* ptext = pFile; char tagName[32]; if (!FindNextTag(ptext)) { char buf[128]; sprintf(buf, "%s - empty file", filename); BuildErrorPanel(buf); return; } int size_x = WSIZE_X; int size_y = WSIZE_Y; int upperBound = YRES(10); int lowerBound; CSchemeManager *pSchemes = gViewPort->GetSchemeManager(); SchemeHandle_t hTextScheme = pSchemes->getSchemeHandle( "Default Text" ); // SchemeHandle_t hTextScheme = pSchemes->getSchemeHandle( "Title Font" ); Font *pDefaultFont = pSchemes->getFont( hTextScheme ); ptext++; int hasParams = GetTagName(ptext, tagName); char panelImage[32]; char buttonImage[32]; char scrollImage[32]; panelImage[0] = 0; buttonImage[0] = 0; scrollImage[0] = 0; int butclr_r = 255, butclr_g = 255, butclr_b = 255, butclr_a = 0; int scroll_x = 0, scroll_y = 0, scroll_wide = 0, scroll_tall = 0; // parse HEAD section if(!strcmp(tagName, "HEAD")) { if (hasParams) { char paramName[32]; char paramValue[32]; while( GetTagParameter(ptext, paramName, paramValue) ) { if (!strcmp(paramName, "xsize")) size_x = XRES(atoi(paramValue)); else if (!strcmp(paramName, "ysize")) size_y = YRES(atoi(paramValue)); else if (!strcmp(paramName, "defaultfont")) { hTextScheme = pSchemes->getSchemeHandle( paramValue ); pDefaultFont = pSchemes->getFont( hTextScheme ); } else if (!strcmp(paramName, "background")) strcpy(panelImage, paramValue); else if (!strcmp(paramName, "imgscroll")) strcpy(scrollImage, paramValue); else if (!strcmp(paramName, "imgbutton")) strcpy(buttonImage, paramValue); else if (!strcmp(paramName, "buttoncolor")) ParseColor(paramValue, butclr_r, butclr_g, butclr_b, butclr_a); else if (!strcmp(paramName, "scrollpos")) ParseColor(paramValue, scroll_x, scroll_y, scroll_wide, scroll_tall); else gEngfuncs.Con_Printf("File %s - unknown HEAD parameter: [%s]\n", filename, paramName); } } if (!FindNextTag(ptext)) { char buf[128]; sprintf(buf, "%s - got nothing, except HEAD", filename); BuildErrorPanel(buf); return; } ptext++; hasParams = GetTagName(ptext, tagName); } // create main panel panel = new CMainPanel(panelImage, (getWide()-size_x)/2, (getTall()-size_y)/2, size_x, size_y); panel->setParent(this); AddToRenderList(panel); // panel->setBgColor(0, 0, 0, 100); // panel->setBorder(new LineBorder); ResetBackground(); // create closing button int butX, butY; CMyButton* button = new CMyButton("", buttonImage, 0, 0); button->setParent(panel); button->setFont(pDefaultFont); button->setText(" Close "); AddToRenderList(button); button->addActionSignal(this); button->getSize(butX, butY); button->setFgColor(butclr_r, butclr_g, butclr_b, butclr_a); butX = panel->getWide() - butX - XRES(10); butY = panel->getTall() - butY - YRES(10); button->setPos( butX, butY ); lowerBound = butY - YRES(10); /* CCheckButton2* pSwitch = new CCheckButton2(); pSwitch->setParent(panel); pSwitch->SetImages("gfx/vgui/checked.tga", "gfx/vgui/unchecked.tga"); pSwitch->SetText("Dont draw world"); pSwitch->setPos(XRES(10), butY); pSwitch->SetCheckboxLeft(true); pSwitch->SetChecked(g_DontDrawWorld ? true : false); pSwitch->SetHandler(this);*/ // parse TITLE section if(!strcmp(tagName, "TITLE")) { Label* pTitle = new Label("", XRES(10), upperBound, panel->getWide() - XRES(20), pDefaultFont->getTall()+YRES(8)); pTitle->setParent(panel); pTitle->setPaintBackgroundEnabled(false); pTitle->setFont(pDefaultFont); // default font pTitle->setFgColor(255, 255, 255, 0); // default color pTitle->setContentAlignment( Label::a_center ); // default alignment if (hasParams) { char paramName[32]; char paramValue[32]; while( GetTagParameter(ptext, paramName, paramValue) ) { if (!strcmp(paramName, "font")) { SchemeHandle_t hTitleScheme = pSchemes->getSchemeHandle(paramValue); Font* pTitleFont = pSchemes->getFont( hTitleScheme ); pTitle->setFont(pTitleFont); pTitle->setSize(panel->getWide() - XRES(20), pTitleFont->getTall()+YRES(8)); } else if (!strcmp(paramName, "color")) { int r, g, b, a; ParseColor(paramValue, r, g, b, a); pTitle->setFgColor(r, g, b, a); } else if (!strcmp(paramName, "align")) { if (!strcmp(paramValue, "left")) pTitle->setContentAlignment( Label::a_west ); else if (!strcmp(paramValue, "right")) pTitle->setContentAlignment( Label::a_east ); else if (!strcmp(paramValue, "center")) pTitle->setContentAlignment( Label::a_center ); else gEngfuncs.Con_Printf("File %s - unknown align value: [%s]\n", filename, paramValue); } else gEngfuncs.Con_Printf("File %s - unknown TITLE parameter: [%s]\n", filename, paramName); } } upperBound = YRES(20) + pTitle->getTall(); char* titleStart = ptext; int haveNextTag = FindNextTag(ptext); int titleLength = ptext - titleStart + 1; pTitle->setText(titleLength, titleStart); if (!haveNextTag) return; ptext++; hasParams = GetTagName(ptext, tagName); } // scroll panel begins if (!scroll_wide) { scroll_wide = size_x * 0.8; scroll_tall = size_y * 0.6; scroll_x = (size_x - scroll_wide) / 2; scroll_y = (size_y - scroll_tall) / 2; } else { scroll_wide = XRES(scroll_wide); scroll_tall = YRES(scroll_tall); scroll_x = XRES(scroll_x); scroll_y = YRES(scroll_y); } button->setPos( scroll_x, scroll_y + scroll_tall + YRES(15) ); // m_pScrollPanel = new CMyScrollPanel(scrollImage, XRES(40), upperBound, panel->getWide()-XRES(80), lowerBound - upperBound ); m_pScrollPanel = new CMyScrollPanel(scrollImage, scroll_x, scroll_y, scroll_wide, scroll_tall ); m_pScrollPanel->setParent(panel); AddToRenderList(m_pScrollPanel); panel->SetDrawBorder(m_pScrollPanel); // pScrollPanel->setBorder( new LineBorder(Color(0,0,0,0)) ); m_pScrollPanel->setScrollBarAutoVisible(true, true); m_pScrollPanel->setScrollBarVisible(false, false); m_pScrollPanel->validate(); // including panel int panelsize = YRES(5); Panel* pDocument = new Panel(0, 0, m_pScrollPanel->getClientClip()->getWide(), 64); pDocument->setParent(m_pScrollPanel->getClient()); pDocument->setPaintBackgroundEnabled(false); // pDocument->setBgColor(0, 0, 0, 100); // reading document elements while(1) { // parse text field if(!strcmp(tagName, "TEXT")) { TextPanel* pTextPanel = new TextPanel("", XRES(5), panelsize, pDocument->getWide() - XRES(10), 64); pTextPanel->setParent(pDocument); pTextPanel->setPaintBackgroundEnabled(false); pTextPanel->setFont(pDefaultFont); // default font pTextPanel->setFgColor(255, 255, 255, 0); // default color int dspace = 0; bool bgColorSet = false; if (hasParams) { char paramName[32]; char paramValue[32]; while( GetTagParameter(ptext, paramName, paramValue) ) { if (!strcmp(paramName, "font")) { SchemeHandle_t hTextScheme = pSchemes->getSchemeHandle(paramValue); Font* pTextFont = pSchemes->getFont( hTextScheme ); pTextPanel->setFont(pTextFont); } else if (!strcmp(paramName, "color")) { int r, g, b, a; ParseColor(paramValue, r, g, b, a); pTextPanel->setFgColor(r, g, b, a); } else if (!strcmp(paramName, "bgcolor")) { int r, g, b, a; ParseColor(paramValue, r, g, b, a); pTextPanel->setPaintBackgroundEnabled(true); pTextPanel->setBgColor(r, g, b, a); bgColorSet = true; } else if (!strcmp(paramName, "lspace")) { int tmp_posx, tmp_posy, tmp_sizex, tmp_sizey; pTextPanel->getBounds(tmp_posx, tmp_posy, tmp_sizex, tmp_sizey); int ofs = XRES(atoi(paramValue)); pTextPanel->setBounds(tmp_posx + ofs, tmp_posy, tmp_sizex - ofs, tmp_sizey); } else if (!strcmp(paramName, "rspace")) { int tmp_sizex, tmp_sizey; pTextPanel->getSize(tmp_sizex, tmp_sizey); int ofs = XRES(atoi(paramValue)); pTextPanel->setSize(tmp_sizex - ofs, tmp_sizey); } else if (!strcmp(paramName, "dspace")) { dspace = YRES(atoi(paramValue)); } else if (!strcmp(paramName, "uspace")) { int x, y; pTextPanel->getPos(x, y); int uspace = YRES(atoi(paramValue)); y += uspace; panelsize += uspace; pTextPanel->setPos(x, y); } else gEngfuncs.Con_Printf("File %s - unknown TEXT parameter: [%s]\n", filename, paramName); } } char* textStart = ptext; int haveNextTag = FindNextTag(ptext); int textLength = ptext - textStart + 1; pTextPanel->getTextImage()->setText(textLength, textStart); pTextPanel->getTextImage()->setSize( pTextPanel->getWide(), pTextPanel->getTall() ); int wrappedX, wrappedY; pTextPanel->getTextImage()->getTextSizeWrapped(wrappedX, wrappedY); if (bgColorSet) { int x, y, realY, unused; pTextPanel->setSize( m_pScrollPanel->getClientClip()->getWide() , wrappedY ); pTextPanel->getTextImage()->setSize( wrappedX , wrappedY ); pTextPanel->getPos(x, realY); pTextPanel->getTextImage()->getPos(unused, y); pTextPanel->getTextImage()->setPos(x, y); pTextPanel->setPos(0, realY); } else pTextPanel->setSize( wrappedX , wrappedY ); panelsize += (wrappedY + dspace); if (!haveNextTag) break; // no more tags ptext++; hasParams = GetTagName(ptext, tagName); } // parse image parameters else if(!strcmp(tagName, "IMG")) { if (hasParams) { char paramName[32]; char paramValue[32]; BitmapTGA* pImage = NULL; int uspace = 0; int dspace = 0; int align = 0; // 0 - center, 1 - left, 2 - right while( GetTagParameter(ptext, paramName, paramValue) ) { if (!strcmp(paramName, "src")) { static int resArray[] = { 320, 400, 512, 640, 800, 1024, 1152, 1280, 1600 }; if (pImage) { gEngfuncs.Con_Printf("File %s - ignoring [src] parameter - already has an image\n", filename); continue; } // try to load image directly pImage = vgui_LoadTGA(paramValue); if (!pImage) { //resolution based image. // should contain %d substring int resArrayIndex = 0; int i = 0; while ((resArray[i] <= ScreenWidth) && (i < 9)) { resArrayIndex = i; i++; } while(pImage == NULL && resArrayIndex >= 0) { char imgName[64]; sprintf(imgName, paramValue, resArray[resArrayIndex]); // gEngfuncs.Con_Printf("=== trying to load: %s\n", imgName); pImage = vgui_LoadTGA(imgName); resArrayIndex--; } } if (!pImage) { // still no image gEngfuncs.Con_Printf("File %s - image not loaded: [%s]\n", filename, paramValue); } } else if (!strcmp(paramName, "align")) { if (!strcmp(paramValue, "left")) align = 1; else if (!strcmp(paramValue, "right")) align = 2; else if (!strcmp(paramValue, "center")) align = 3; else gEngfuncs.Con_Printf("File %s - unknown align value: [%s]\n", filename, paramValue); } else if (!strcmp(paramName, "uspace")) uspace = YRES(atoi(paramValue)); else if (!strcmp(paramName, "dspace")) dspace = YRES(atoi(paramValue)); else gEngfuncs.Con_Printf("File %s - unknown IMG parameter: [%s]\n", filename, paramName); } // create image panel if (pImage) { int tmp_x, tmp_y; pImage->getSize(tmp_x, tmp_y); switch (align) { case 0: tmp_x = (pDocument->getWide() - tmp_x) / 2; break; case 1: default: tmp_x = 0; break; case 2: tmp_x = pDocument->getWide() - tmp_x; break; } Label *pImg = new Label("", tmp_x, panelsize + uspace); pImg->setParent(pDocument); pImg->setImage(pImage); pImg->setPaintBackgroundEnabled(false); panelsize = panelsize + uspace + tmp_y + dspace; } } else { gEngfuncs.Con_Printf("File %s - IMG with no parameters\n", filename); } if (!FindNextTag(ptext)) break; ptext++; hasParams = GetTagName(ptext, tagName); } // unknown tag else { gEngfuncs.Con_Printf("File %s - unknown tag: [%s]\n", filename, tagName); if (!FindNextTag(ptext)) break; // no more tags ptext++; hasParams = GetTagName(ptext, tagName); } } gEngfuncs.COM_FreeFile(pFile); // document is ready, panelsize now contains the height of panel panelsize += YRES(5); int doc_x = pDocument->getWide(); pDocument->setSize(doc_x, panelsize); m_pScrollPanel->validate(); m_iMaxScrollValue = panelsize - m_pScrollPanel->getClientClip()->getTall(); } void CParanoiaTextPanel::paint() { if (panel && !panel->IsTgaPanel( )) { float curtime = gEngfuncs.GetClientTime(); float delta = (curtime - m_flStartTime) / 0.5; if (delta > 1) delta = 1; int x, y, wide, tall; panel->getBounds(x, y, wide, tall); drawSetColor(0, 0, 0, 255 - (int)(delta * 120)); drawFilledRect(0, 0, getWide(), y); drawFilledRect(0, y+tall, getWide(), getTall()); drawFilledRect(0, y, x, y+tall); drawFilledRect(x+wide, y, getWide(), y+tall); } } void CParanoiaTextPanel::actionPerformed(Panel* panel) { CloseWindow(); } // return 0 to hook key // return 1 to allow key int CParanoiaTextPanel::KeyInput(int down, int keynum, const char *pszCurrentBinding) { if (!down) return 1; // dont disable releasing of the keys switch (keynum) { // close window case K_ENTER: case K_ESCAPE: { CloseWindow(); return 0; } // mouse and arrows key scroll case K_MWHEELUP: case K_UPARROW: case K_KP_UPARROW: { int hor, ver; m_pScrollPanel->getScrollValue(hor, ver); ver -= YRES(30); if (ver < 0) ver = 0; m_pScrollPanel->setScrollValue(hor, ver); return 0; } case K_MWHEELDOWN: case K_DOWNARROW: case K_KP_DOWNARROW: { int hor, ver; m_pScrollPanel->getScrollValue(hor, ver); ver += YRES(30); if (ver > m_iMaxScrollValue) ver = m_iMaxScrollValue; m_pScrollPanel->setScrollValue(hor, ver); return 0; } // keyboard page listing case K_HOME: case K_KP_HOME: { int hor, ver; m_pScrollPanel->getScrollValue(hor, ver); m_pScrollPanel->setScrollValue(hor, 0); return 0; } case K_END: case K_KP_END: { int hor, ver; m_pScrollPanel->getScrollValue(hor, ver); m_pScrollPanel->setScrollValue(hor, m_iMaxScrollValue); return 0; } case K_PGDN: case K_KP_PGDN: { int hor, ver; m_pScrollPanel->getScrollValue(hor, ver); ver += m_pScrollPanel->getClientClip()->getTall(); if (ver > m_iMaxScrollValue) ver = m_iMaxScrollValue; m_pScrollPanel->setScrollValue(hor, ver); return 0; } case K_PGUP: case K_KP_PGUP: { int hor, ver; m_pScrollPanel->getScrollValue(hor, ver); ver -= m_pScrollPanel->getClientClip()->getTall(); if (ver < 0) ver = 0; m_pScrollPanel->setScrollValue(hor, ver); return 0; } // Wargon: Консоль, функциональные клавиши и кнопки мыши пропускаются. case 96: case 126: case K_F1: case K_F2: case K_F3: case K_F4: case K_F5: case K_F6: case K_F7: case K_F8: case K_F9: case K_F10: case K_F11: case K_F12: case K_MOUSE1: case K_MOUSE2: case K_MOUSE3: case K_MOUSE4: case K_MOUSE5: return 1; } // Wargon: Все остальные клавиши блокируются. return 0; } void CParanoiaTextPanel::CloseWindow() { setVisible(false); gViewPort->UpdateCursorState(); } void CParanoiaTextPanel::ResetBackground() { m_flStartTime = gEngfuncs.GetClientTime(); } void CParanoiaTextPanel::AddToRenderList(CRenderable* pnew) { if (m_iRenderElms < 4) { m_pRenderList[m_iRenderElms] = pnew; m_iRenderElms++; } else gEngfuncs.Con_Printf("ERROR: too many renderable objects!\n"); } void OrthoVGUI(void) { if (gViewPort && gViewPort->m_pParanoiaText && gViewPort->m_pParanoiaText->isVisible()) gViewPort->m_pParanoiaText->Render(); } //void CParanoiaTextPanel::StateChanged(CCheckButton2 *pButton) //{ // g_DontDrawWorld = !g_DontDrawWorld; //}