diff --git a/.gitmodules b/.gitmodules index 25dfc14..1fc267e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "vgui-dev"] path = vgui-dev url = https://github.com/FWGS/vgui-dev +[submodule "vgui2-dev"] + path = vgui2-dev + url = https://github.com/kungfulon/vgui2-dev.git diff --git a/vgui2-dev b/vgui2-dev new file mode 160000 index 0000000..bb7fdba --- /dev/null +++ b/vgui2-dev @@ -0,0 +1 @@ +Subproject commit bb7fdba43994bf27934d75d5031d917a448e1010 diff --git a/vgui2_gameui.cpp b/vgui2_gameui.cpp new file mode 100644 index 0000000..6d7e79c --- /dev/null +++ b/vgui2_gameui.cpp @@ -0,0 +1,76 @@ +/* +vgui2_gameui.cpp - implement IGameUIFuncs for vgui2 support +Copyright (C) 2022 FWGS + +This program 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 3 of the License, or +(at your option) any later version. + +This program 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. + +In addition, as a special exception, the author gives permission +to link the code of this program with VGUI library developed by +Valve, L.L.C ("Valve"). You must obey the GNU General Public License +in all respects for all of the code used other than VGUI library. +If you modify this file, you may extend this exception to your +version of the file, but you are not obligated to do so. If +you do not wish to do so, delete this exception statement +from your version. + +*/ + +#include "vgui2_gameui.h" +#include + +namespace vgui_support +{ +extern vguiapi_t *g_api; +}; + +bool GameUIFuncs::IsKeyDown( const char *keyname, bool &isdown ) +{ + isdown = false; + return false; +} + +const char *GameUIFuncs::Key_NameForKey( int keynum ) +{ + return ""; +} + +const char *GameUIFuncs::Key_BindingForKey( int keynum ) +{ + return ""; +} + +vgui2::KeyCode GameUIFuncs::GetVGUI2KeyCodeForBind( const char *bind ) +{ + return vgui2::KEY_TAB; + // return ( vgui2::KeyCode )( vgui_support::g_api->KeyForBind( bind ) + 1 ); +} + +void GameUIFuncs::GetVideoModes( vmode_t **liststart, int *count ) +{ +} + +void GameUIFuncs::GetCurrentVideoMode( int *wide, int *tall, int *bpp ) +{ +} + +void GameUIFuncs::GetCurrentRenderer( char *name, int namelen, int *windowed, int *hdmodels, int *addons_folder, int *vid_level ) +{ +} + +bool GameUIFuncs::IsConnectedToVACSecureServer() +{ + return false; +} + +int GameUIFuncs::Key_KeyStringToKeyNum( const char *pchKey ) +{ + return 0; +} diff --git a/vgui2_gameui.h b/vgui2_gameui.h new file mode 100644 index 0000000..f8010b9 --- /dev/null +++ b/vgui2_gameui.h @@ -0,0 +1,45 @@ +/* +vgui2_gameui.h - vgui2 GameUIFuncs header +Copyright (C) 2022 FWGS + +This program 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 3 of the License, or +(at your option) any later version. + +This program 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. + +In addition, as a special exception, the author gives permission +to link the code of this program with VGUI library developed by +Valve, L.L.C ("Valve"). You must obey the GNU General Public License +in all respects for all of the code used other than VGUI library. +If you modify this file, you may extend this exception to your +version of the file, but you are not obligated to do so. If +you do not wish to do so, delete this exception statement +from your version. + +*/ + +#ifndef VGUI2_GAMEUI_H +#define VGUI2_GAMEUI_H + +#include + +class GameUIFuncs : public IGameUIFuncs +{ +public: + bool IsKeyDown( const char *keyname, bool &isdown ) override; + const char *Key_NameForKey( int keynum ) override; + const char *Key_BindingForKey( int keynum ) override; + vgui2::KeyCode GetVGUI2KeyCodeForBind( const char *bind ) override; + void GetVideoModes( vmode_t **liststart, int *count ) override; + void GetCurrentVideoMode( int *wide, int *tall, int *bpp ) override; + void GetCurrentRenderer( char *name, int namelen, int *windowed, int *hdmodels, int *addons_folder, int *vid_level ) override; + bool IsConnectedToVACSecureServer() override; + int Key_KeyStringToKeyNum( const char *pchKey ) override; +}; + +#endif // VGUI2_GAMEUI_H diff --git a/vgui2_int.cpp b/vgui2_int.cpp new file mode 100644 index 0000000..f7b8c84 --- /dev/null +++ b/vgui2_int.cpp @@ -0,0 +1,377 @@ +/* +vgui2_int.cpp - vgui2 dll interaction +Copyright (C) 2022 FWGS + +This program 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 3 of the License, or +(at your option) any later version. + +This program 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. + +In addition, as a special exception, the author gives permission +to link the code of this program with VGUI library developed by +Valve, L.L.C ("Valve"). You must obey the GNU General Public License +in all respects for all of the code used other than VGUI library. +If you modify this file, you may extend this exception to your +version of the file, but you are not obligated to do so. If +you do not wish to do so, delete this exception statement +from your version. + +*/ + +#include +#include +#include "vgui2_surf.h" +#include "vgui2_gameui.h" +#include +#include +#include +#include +#include + +namespace vgui_support +{ +extern vguiapi_t *g_api; +}; + +class RootPanel : public vgui2::Panel +{ +public: + RootPanel( vgui2::Panel *parent, const char *panelName ) : vgui2::Panel( parent, panelName ) { } + + vgui2::VPANEL IsWithinTraverse( int x, int y, bool traversePopups ) override + { + auto panel = vgui2::Panel::IsWithinTraverse( x, y, traversePopups ); + if ( panel == GetVPanel() ) + return NULL; + + return panel; + } +}; + +class BaseUI : public IBaseUI +{ +public: + BaseUI() : initialized( 0 ), numFactories( 0 ) { } + void Initialize( CreateInterfaceFn *factories, int count ) override; + void Start( int width, int height ) override; + void Shutdown() override; + int Key_Event( int down, int keynum, const char *pszCurrentBinding ) override; + void CallEngineSurfaceAppHandler( void *event, void *userData ) override; + void Paint( int x, int y, int right, int bottom ) override; + void HideGameUI() override; + void ActivateGameUI() override; + void HideConsole() override; + void ShowConsole() override; + +private: + static constexpr int MAX_NUM_FACTORIES = 6; + + int initialized; + CreateInterfaceFn factoryList[MAX_NUM_FACTORIES]; + int numFactories; + void *vgui2Module; + void *chromeModule; +}; + +static RootPanel *rootPanel; +static IClientVGUI *clientVGUI; +static void *fileSystemModule; +static IVFileSystem009 *fileSystem; + +static VGUI2Surface vgui2Surface; +static BaseUI baseUI; +static GameUIFuncs gameUIFuncs; + +static inline void *LoadModule( const char *module ) +{ + return vgui_support::g_api->COM_LoadLibrary( module, false, false ); +} + +static inline CreateInterfaceFn GetFactory( void *module ) +{ + return (CreateInterfaceFn)vgui_support::g_api->COM_GetProcAddress( module, "CreateInterface" ); +} + +static inline void UnloadModule( void *module ) +{ + vgui_support::g_api->COM_FreeLibrary( module ); +} + +void BaseUI::Initialize( CreateInterfaceFn *factories, int count ) +{ + if ( initialized ) + return; + + vgui2Module = LoadModule( "vgui2." OS_LIB_EXT ); + chromeModule = LoadModule( "chromehtml." OS_LIB_EXT ); + + factoryList[numFactories++] = factories[0]; + factoryList[numFactories++] = GetFactory( vgui2Module ); + factoryList[numFactories++] = factories[1]; + factoryList[numFactories++] = GetFactory( chromeModule ); + + if ( factories[2] != nullptr ) + { + factoryList[numFactories++] = factories[2]; + clientVGUI = (IClientVGUI *)factoryList[4]( VCLIENTVGUI_INTERFACE_VERSION, nullptr ); + } + + vgui2::InitializeVGui2Interfaces( "BaseUI", factoryList, numFactories ); + + initialized = 1; +} + +void BaseUI::Start( int width, int height ) +{ + if ( !initialized ) + return; + + rootPanel = new RootPanel( nullptr, "RootPanel" ); + rootPanel->SetCursor( vgui2::dc_none ); + rootPanel->SetBounds( 0, 0, width, height ); + rootPanel->SetPaintBorderEnabled( false ); + rootPanel->SetPaintBackgroundEnabled( false ); + rootPanel->SetPaintEnabled( false ); + rootPanel->SetVisible( true ); + rootPanel->SetZPos( 0 ); + + auto chromeController = (IHTMLChromeController *)factoryList[3]( CHROME_HTML_CONTROLLER_INTERFACE_VERSION, nullptr ); + vgui2Surface.Init( rootPanel->GetVPanel(), chromeController ); + vgui2Surface.SetIgnoreMouseVisCalc( true ); + + vgui2::scheme()->LoadSchemeFromFile( "resource/trackerscheme.res", "BaseUI" ); + + vgui2::localize()->AddFile( vgui2::filesystem(), "resource/platform_%language%.txt" ); + vgui2::localize()->AddFile( vgui2::filesystem(), "resource/vgui_%language%.txt" ); + vgui2::localize()->AddFile( vgui2::filesystem(), "resource/gameui_%language%.txt" ); + vgui2::localize()->AddFile( vgui2::filesystem(), "resource/valve_%language%.txt" ); + + char szMod[32]; + vgui2::system()->GetCommandLineParamValue( "-game", szMod, sizeof( szMod ) ); + char szLocalizeFile[260]; + Q_snprintf( szLocalizeFile, sizeof( szLocalizeFile ), "resource/%s_%%language%%.txt", szMod ); + szLocalizeFile[sizeof( szLocalizeFile ) - 1] = '\0'; + vgui2::localize()->AddFile( vgui2::filesystem(), szLocalizeFile ); + + // TODO: Load localization from fallback directory + + vgui2::ivgui()->Start(); + vgui2::ivgui()->SetSleep( false ); + + if ( clientVGUI ) + clientVGUI->Initialize( factoryList, numFactories ); + + rootPanel->SetScheme( "ClientScheme" ); + + if ( clientVGUI ) + { + clientVGUI->Start(); + clientVGUI->SetParent( rootPanel->GetVPanel() ); + } + + vgui2Surface.SetIgnoreMouseVisCalc( false ); +} + +void BaseUI::Shutdown() +{ + if ( !initialized ) + return; + + vgui2::ivgui()->RunFrame(); + vgui2::ivgui()->Shutdown(); + + if ( clientVGUI ) + { + clientVGUI->Shutdown(); + clientVGUI = nullptr; + } + + vgui2::system()->SaveUserConfigFile(); + vgui2::surface()->Shutdown(); + + UnloadModule( chromeModule ); + chromeModule = nullptr; + UnloadModule( vgui2Module ); + vgui2Module = nullptr; +} + +int BaseUI::Key_Event( int down, int keynum, const char *pszCurrentBinding ) +{ + if ( !initialized ) + return 0; + + return vgui2::surface()->NeedKBInput(); +} + +void BaseUI::CallEngineSurfaceAppHandler( void *event, void *userData ) +{ +} + +void BaseUI::Paint( int x, int y, int right, int bottom ) +{ + if ( !initialized ) + return; + + vgui2::VPANEL panel = vgui2::surface()->GetEmbeddedPanel(); + if ( panel == NULL ) + return; + + vgui2::ivgui()->RunFrame(); + vgui2Surface.SetScreenBounds( x, y, right - x, bottom - y ); + rootPanel->SetBounds( 0, 0, right, bottom ); + rootPanel->Repaint(); + vgui2::surface()->PaintTraverse( panel ); + vgui2::surface()->CalculateMouseVisible(); +} + +void BaseUI::HideGameUI() +{ +} + +void BaseUI::ActivateGameUI() +{ +} + +void BaseUI::HideConsole() +{ +} + +void BaseUI::ShowConsole() +{ +} + +extern "C" EXPORT IBaseInterface *CreateInterface( const char *pName, int *pReturnCode ) +{ + if ( pReturnCode ) *pReturnCode = IFACE_OK; + + if ( !Q_strcmp( pName, BASEUI_INTERFACE_VERSION ) ) + return (IBaseUI *)&baseUI; + + if ( !Q_strcmp( pName, VGUI_SURFACE_INTERFACE_VERSION ) ) + return (vgui2::ISurface *)&vgui2Surface; + + if ( !Q_strcmp( pName, VENGINE_GAMEUIFUNCS_VERSION ) ) + return (IGameUIFuncs *)&gameUIFuncs; + + if ( pReturnCode ) *pReturnCode = IFACE_FAILED; + return nullptr; +} + +void VGUI2_Startup( const char *clientlib, int width, int height ) +{ + if ( rootPanel == nullptr ) + { + fileSystemModule = LoadModule( "filesystem_stdio." OS_LIB_EXT ); + auto fileSystemFactory = GetFactory( fileSystemModule ); + fileSystem = (IVFileSystem009 *)fileSystemFactory( "VFileSystem009", nullptr ); + + CreateInterfaceFn factories[3]; + factories[0] = CreateInterface; + factories[1] = fileSystemFactory; + factories[2] = GetFactory( LoadModule( clientlib ) ); + + baseUI.Initialize( factories, 3 ); + baseUI.Start( width, height ); + } + + rootPanel->SetBounds( 0, 0, width, height ); +} + +void VGUI2_Shutdown( void ) +{ + if ( rootPanel == nullptr ) + return; + + baseUI.Shutdown(); + fileSystemModule = nullptr; + fileSystem = nullptr; +} + +void VGUI2_ScreenSize( int &width, int &height ) +{ + if ( rootPanel ) + rootPanel->GetSize( width, height ); +} + +bool VGUI2_UseVGUI1( void ) +{ + if ( clientVGUI ) + return clientVGUI->UseVGUI1(); + return true; +} + +void VGUI2_Paint( void ) +{ + if ( rootPanel == nullptr ) + return; + + int wide, tall; + VGUI2_ScreenSize( wide, tall ); + baseUI.Paint( 0, 0, wide, tall ); +} + +void VGUI2_Key( VGUI_KeyAction action, VGUI_KeyCode code ) +{ + if ( rootPanel == nullptr ) + return; + + if ( !baseUI.Key_Event( action == KA_PRESSED, code + 1, "" ) ) + return; + + switch ( action ) + { + case KA_PRESSED: + vgui2::inputinternal()->InternalKeyCodePressed( ( vgui2::KeyCode )( code + 1 ) ); + break; + case KA_RELEASED: + vgui2::inputinternal()->InternalKeyCodeReleased( ( vgui2::KeyCode )( code + 1 ) ); + break; + case KA_TYPED: + vgui2::inputinternal()->InternalKeyCodeTyped( ( vgui2::KeyCode )( code + 1 ) ); + break; + } +} + +void VGUI2_Mouse( VGUI_MouseAction action, int code ) +{ + if ( rootPanel == nullptr ) + return; + + if ( !vgui2::surface()->IsCursorVisible() ) + return; + + switch ( action ) + { + case MA_PRESSED: + vgui2::inputinternal()->InternalMousePressed( (vgui2::MouseCode)code ); + break; + case MA_RELEASED: + vgui2::inputinternal()->InternalMouseReleased( (vgui2::MouseCode)code ); + break; + case MA_DOUBLE: + vgui2::inputinternal()->InternalMouseDoublePressed( (vgui2::MouseCode)code ); + break; + case MA_WHEEL: + vgui2::inputinternal()->InternalMouseWheeled( code ); + break; + } +} + +void VGUI2_MouseMove( int x, int y ) +{ + if ( rootPanel == nullptr ) + return; + + vgui2::inputinternal()->InternalCursorMoved( x, y ); +} + +void VGUI2_TextInput( const char *text ) +{ + for ( const char *c = text; *c; c++ ) + vgui2::inputinternal()->InternalKeyTyped( *c ); +} diff --git a/vgui2_surf.cpp b/vgui2_surf.cpp new file mode 100644 index 0000000..4fc1ece --- /dev/null +++ b/vgui2_surf.cpp @@ -0,0 +1,770 @@ +/* +vgui2_surf.cpp - vgui2 surface implementation +Copyright (C) 2022 FWGS + +This program 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 3 of the License, or +(at your option) any later version. + +This program 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. + +In addition, as a special exception, the author gives permission +to link the code of this program with VGUI library developed by +Valve, L.L.C ("Valve"). You must obey the GNU General Public License +in all respects for all of the code used other than VGUI library. +If you modify this file, you may extend this exception to your +version of the file, but you are not obligated to do so. If +you do not wish to do so, delete this exception statement +from your version. + +*/ + +#include "vgui2_surf.h" +#include +#include +#include + +namespace vgui_support +{ +extern vguiapi_t *g_api; +}; + +void VGUI2_ScreenSize( int &width, int &height ); + +static const auto VPANEL_NORMAL = ( (vgui2::SurfacePlat *)NULL ); +static const auto VPANEL_MINIMIZED = ( (vgui2::SurfacePlat *)0x00000001 ); + +void VGUI2Surface::Shutdown() +{ + if ( chromeController ) + chromeController->Shutdown(); +} + +void VGUI2Surface::RunFrame() +{ + if ( chromeController ) + chromeController->RunFrame(); +} + +vgui2::VPANEL VGUI2Surface::GetEmbeddedPanel() +{ + return embeddedPanel; +} + +void VGUI2Surface::SetEmbeddedPanel( vgui2::VPANEL panel ) +{ + embeddedPanel = panel; +} + +void VGUI2Surface::PushMakeCurrent( vgui2::VPANEL panel, bool useInsets ) +{ + int insets[4] = { 0, 0, 0, 0 }; + int absExtents[4]; + int clipRect[4]; + int wide, tall; + + if ( useInsets ) + vgui2::ipanel()->GetInset( panel, insets[0], insets[1], insets[2], insets[3] ); + + vgui2::ipanel()->GetAbsPos( panel, absExtents[0], absExtents[1] ); + vgui2::ipanel()->GetSize( panel, wide, tall ); + absExtents[2] = absExtents[0] + wide; + absExtents[3] = absExtents[1] + tall; + + vgui2::ipanel()->GetClipRect( panel, clipRect[0], clipRect[1], clipRect[2], clipRect[3] ); + + // engineSurface->PushMakeCurrent( insets, absExtents, clipRect ); +} + +void VGUI2Surface::PopMakeCurrent( vgui2::VPANEL panel ) +{ + // engineSurface->PopMakeCurrent(); +} + +void VGUI2Surface::DrawSetColor( int r, int g, int b, int a ) +{ + // engineSurface->DrawSetColor( r, g, b, a ); +} + +void VGUI2Surface::DrawSetColor( Color col ) +{ + // engineSurface->DrawSetColor( col[0], col[1], col[2], col[3] ); +} + +void VGUI2Surface::DrawFilledRect( int x0, int y0, int x1, int y1 ) +{ + // engineSurface->DrawFilledRect( x0, y0, x1, y1 ); +} + +void VGUI2Surface::DrawOutlinedRect( int x0, int y0, int x1, int y1 ) +{ + // engineSurface->DrawOutlinedRect( x0, y0, x1, y1 ); +} + +void VGUI2Surface::DrawLine( int x0, int y0, int x1, int y1 ) +{ + // engineSurface sucks +} + +void VGUI2Surface::DrawPolyLine( int *px, int *py, int numPoints ) +{ + // engineSurface sucks +} + +void VGUI2Surface::DrawSetTextFont( vgui2::HFont font ) +{ + // engineSurface->DrawSetTextFont( font ); +} + +void VGUI2Surface::DrawSetTextColor( int r, int g, int b, int a ) +{ + // engineSurface->DrawSetTextColor( r, g, b, a ); +} + +void VGUI2Surface::DrawSetTextColor( Color col ) +{ + // engineSurface->DrawSetTextColor( col[0], col[1], col[2], col[3] ); +} + +void VGUI2Surface::DrawSetTextPos( int x, int y ) +{ + // engineSurface->DrawSetTextPos( x, y ); +} + +void VGUI2Surface::DrawGetTextPos( int &x, int &y ) +{ + // engineSurface->DrawGetTextPos( x, y ); +} + +void VGUI2Surface::DrawPrintText( const wchar_t *text, int textLen ) +{ + // engineSurface->DrawPrintText( text, textLen ); +} + +void VGUI2Surface::DrawUnicodeChar( wchar_t wch ) +{ + // engineSurface->DrawUnicodeChar( wch, false ); +} + +void VGUI2Surface::DrawUnicodeCharAdd( wchar_t wch ) +{ + // engineSurface->DrawUnicodeChar( wch, true ); +} + +void VGUI2Surface::DrawFlushText() +{ +} + +vgui2::IHTML *VGUI2Surface::CreateHTMLWindow( vgui2::IHTMLEvents *events, vgui2::VPANEL context ) +{ + return nullptr; +} + +void VGUI2Surface::PaintHTMLWindow( vgui2::IHTML *htmlwin ) +{ +} + +void VGUI2Surface::DeleteHTMLWindow( vgui2::IHTML *htmlwin ) +{ +} + +void VGUI2Surface::DrawSetTextureFile( int id, const char *filename, int hardwareFilter, bool forceReload ) +{ + // engineSurface->DrawSetTextureFile( id, filename ); +} + +void VGUI2Surface::DrawSetTextureRGBA( int id, const unsigned char *rgba, int wide, int tall, int hardwareFilter, bool forceReload ) +{ + // engineSurface->DrawSetTextureRGBA( id, rgba, wide, tall ); +} + +void VGUI2Surface::DrawSetTexture( int id ) +{ + // engineSurface->DrawSetTexture( id ); +} + +void VGUI2Surface::DrawGetTextureSize( int id, int &wide, int &tall ) +{ + wide = 1; + tall = 1; + // engineSurface->DrawGetTextureSize( id, wide, tall ); +} + +void VGUI2Surface::DrawTexturedRect( int x0, int y0, int x1, int y1 ) +{ + // engineSurface->DrawTexturedRect( x0, y0, x1, y1 ); +} + +bool VGUI2Surface::IsTextureIDValid( int id ) +{ + return true; +} + +int VGUI2Surface::CreateNewTextureID( bool procedural ) +{ + return vgui_support::g_api->GenerateTexture(); +} + +void VGUI2Surface::GetScreenSize( int &wide, int &tall ) +{ + VGUI2_ScreenSize( wide, tall ); +} + +void VGUI2Surface::SetAsTopMost( vgui2::VPANEL panel, bool state ) +{ +} + +void VGUI2Surface::BringToFront( vgui2::VPANEL panel ) +{ + vgui2::ipanel()->MoveToFront( panel ); + + if ( vgui2::ipanel()->IsPopup( panel ) ) + MovePopupToFront( panel ); +} + +void VGUI2Surface::SetForegroundWindow( vgui2::VPANEL panel ) +{ + BringToFront( panel ); +} + +void VGUI2Surface::SetPanelVisible( vgui2::VPANEL panel, bool state ) +{ +} + +void VGUI2Surface::SetMinimized( vgui2::VPANEL panel, bool state ) +{ + if ( !state ) + { + vgui2::ipanel()->SetPlat( panel, VPANEL_NORMAL ); + return; + } + + vgui2::ipanel()->SetPlat( panel, VPANEL_MINIMIZED ); + vgui2::ipanel()->SetVisible( panel, false ); +} + +bool VGUI2Surface::IsMinimized( vgui2::VPANEL panel ) +{ + return vgui2::ipanel()->Plat( panel ) == VPANEL_MINIMIZED; +} + +void VGUI2Surface::FlashWindow( vgui2::VPANEL panel, bool state ) +{ +} + +void VGUI2Surface::SetTitle( vgui2::VPANEL panel, const wchar_t *title ) +{ +} + +void VGUI2Surface::SetAsToolBar( vgui2::VPANEL panel, bool state ) +{ +} + +void VGUI2Surface::CreatePopup( vgui2::VPANEL panel, bool minimised, bool showTaskbarIcon, bool disabled, bool mouseInput, bool kbInput ) +{ + if ( vgui2::ipanel()->GetParent( panel ) == NULL ) + vgui2::ipanel()->SetParent( panel, GetEmbeddedPanel() ); + + vgui2::ipanel()->SetPopup( panel, true ); + vgui2::ipanel()->SetKeyBoardInputEnabled( panel, kbInput ); + vgui2::ipanel()->SetMouseInputEnabled( panel, mouseInput ); + + if ( !popups.hasElement( panel ) ) + popups.addElement( panel ); +} + +void VGUI2Surface::SwapBuffers( vgui2::VPANEL panel ) +{ +} + +void VGUI2Surface::Invalidate( vgui2::VPANEL panel ) +{ +} + +void VGUI2Surface::SetCursor( vgui2::HCursor cursor ) +{ + // These cursors are not available in VGUI1, so ignore them for now. + if ( cursor >= vgui2::dc_last || cursor == vgui2::dc_waitarrow || cursor == vgui2::dc_blank ) + return; + + if ( currentCursor != cursor ) + { + currentCursor = cursor; + + // Hack to make it compatible with VGUI1 + if ( cursor > vgui2::dc_waitarrow ) + --cursor; + + vgui_support::g_api->CursorSelect( (VGUI_DefaultCursor)cursor ); + } +} + +bool VGUI2Surface::IsCursorVisible() +{ + return currentCursor != vgui2::dc_none; +} + +void VGUI2Surface::ApplyChanges() +{ +} + +bool VGUI2Surface::IsWithin( int x, int y ) +{ + return true; +} + +bool VGUI2Surface::HasFocus() +{ + return true; +} + +bool VGUI2Surface::SupportsFeature( SurfaceFeature_e feature ) +{ + return false; +} + +void VGUI2Surface::RestrictPaintToSinglePanel( vgui2::VPANEL panel ) +{ + restrictedPanel = panel; + vgui2::input()->SetAppModalSurface( panel ); +} + +void VGUI2Surface::SetModalPanel( vgui2::VPANEL panel ) +{ +} + +vgui2::VPANEL VGUI2Surface::GetModalPanel() +{ + return restrictedPanel; +} + +void VGUI2Surface::UnlockCursor() +{ + cursorLocked = false; +} + +void VGUI2Surface::LockCursor() +{ + cursorLocked = true; +} + +void VGUI2Surface::SetTranslateExtendedKeys( bool state ) +{ + translateExtendedKeys = state; +} + +vgui2::VPANEL VGUI2Surface::GetTopmostPopup() +{ + if ( popups.getCount() > 0 ) + return popups[popups.getCount() - 1]; + + return NULL; +} + +void VGUI2Surface::SetTopLevelFocus( vgui2::VPANEL panel ) +{ + while ( panel ) + { + if ( vgui2::ipanel()->IsPopup( panel ) && vgui2::ipanel()->IsMouseInputEnabled( panel ) ) + { + BringToFront( panel ); + break; + } + + panel = vgui2::ipanel()->GetParent( panel ); + } +} + +vgui2::HFont VGUI2Surface::CreateFont() +{ + return -1; + // return engineSurface->CreateFont(); +} + +bool VGUI2Surface::AddGlyphSetToFont( vgui2::HFont font, const char *fontName, int tall, int weight, int blur, int scanlines, int flags, int lowRange, int highRange ) +{ + return false; + // return engineSurface->AddGlyphSetToFont( font, fontName, tall, weight, flags & FONTFLAG_ITALIC, flags & FONTFLAG_UNDERLINE, flags & FONTFLAG_STRIKEOUT, flags & FONTFLAG_SYMBOL ); +} + +bool VGUI2Surface::AddCustomFontFile( const char *fontFileName ) +{ + return false; + // return engineSurface->AddCustomFontFile( fontFileName ); +} + +int VGUI2Surface::GetFontTall( vgui2::HFont font ) +{ + return 1; + // return engineSurface->GetFontTall( font ); +} + +void VGUI2Surface::GetCharABCwide( vgui2::HFont font, int ch, int &a, int &b, int &c ) +{ + a = b = c = 1; + // engineSurface->GetCharABCwide( font, ch, a, b, c ); +} + +int VGUI2Surface::GetCharacterWidth( vgui2::HFont font, int ch ) +{ + return 1; + // return engineSurface->GetCharacterWidth( font, ch ); +} + +void VGUI2Surface::GetTextSize( vgui2::HFont font, const wchar_t *text, int &wide, int &tall ) +{ + wide = 1; + tall = 1; + // engineSurface->GetTextSize( font, text, wide, tall ); +} + +vgui2::VPANEL VGUI2Surface::GetNotifyPanel() +{ + return NULL; +} + +void VGUI2Surface::SetNotifyIcon( vgui2::VPANEL context, vgui2::HTexture icon, vgui2::VPANEL panelToReceiveMessages, const char *text ) +{ +} + +void VGUI2Surface::PlaySound( const char *fileName ) +{ + // vgui_support::g_api->PlaySound( fileName ); +} + +int VGUI2Surface::GetPopupCount() +{ + return popups.getCount(); +} + +vgui2::VPANEL VGUI2Surface::GetPopup( int index ) +{ + if ( 0 <= index && index < popups.getCount() ) + return popups[index]; + + return NULL; +} + +bool VGUI2Surface::ShouldPaintChildPanel( vgui2::VPANEL panel ) +{ + if ( restrictedPanel != NULL && vgui2::ipanel()->HasParent( panel, restrictedPanel ) ) + return false; + + if ( !vgui2::ipanel()->IsPopup( panel ) ) + return true; + + if ( popups.hasElement( panel ) ) + vgui2::ipanel()->Render_SetPopupVisible( panel, true ); + + return false; +} + +bool VGUI2Surface::RecreateContext( vgui2::VPANEL panel ) +{ + return true; +} + +void VGUI2Surface::AddPanel( vgui2::VPANEL panel ) +{ + if ( !vgui2::ipanel()->IsPopup( panel ) ) + return; + + CreatePopup( panel, false, false, false, true, true ); +} + +void VGUI2Surface::ReleasePanel( vgui2::VPANEL panel ) +{ + popups.removeElement( panel ); + + if ( restrictedPanel == panel ) + restrictedPanel = NULL; +} + +void VGUI2Surface::MovePopupToFront( vgui2::VPANEL panel ) +{ + if ( popups.hasElement( panel ) ) + { + popups.removeElement( panel ); + popups.addElement( panel ); + } +} + +void VGUI2Surface::MovePopupToBack( vgui2::VPANEL panel ) +{ + if ( popups.hasElement( panel ) ) + { + popups.removeElement( panel ); + popups.insertElementAt( panel, 0 ); + } +} + +void VGUI2Surface::SolveTraverse( vgui2::VPANEL panel, bool forceApplySchemeSettings ) +{ + InternalSchemeSettingsTraverse( panel, forceApplySchemeSettings ); + InternalThinkTraverse( panel ); + InternalSolveTraverse( panel ); +} + +void VGUI2Surface::PaintTraverse( vgui2::VPANEL panel ) +{ + if ( !vgui2::ipanel()->IsVisible( panel ) ) + return; + + if ( panel != GetEmbeddedPanel() ) + { + vgui2::ipanel()->PaintTraverse( panel, true, true ); + return; + } + + if ( restrictedPanel ) + panel = restrictedPanel; + + for ( int i = 0; i < popups.getCount(); ++i ) + vgui2::ipanel()->Render_SetPopupVisible( popups[i], false ); + + vgui2::ipanel()->PaintTraverse( panel, true, true ); + + for ( int i = 0; i < popups.getCount(); ++i ) + { + if ( vgui2::ipanel()->Render_GetPopupVisible( popups[i] ) ) + vgui2::ipanel()->PaintTraverse( popups[i], true, true ); + } +} + +void VGUI2Surface::EnableMouseCapture( vgui2::VPANEL panel, bool state ) +{ +} + +void VGUI2Surface::GetWorkspaceBounds( int &x, int &y, int &wide, int &tall ) +{ + x = 0; + y = 0; + vgui2::ipanel()->GetSize( embeddedPanel, wide, tall ); +} + +void VGUI2Surface::GetAbsoluteWindowBounds( int &x, int &y, int &wide, int &tall ) +{ + x = surfaceBounds[0]; + y = surfaceBounds[1]; + wide = surfaceBounds[2]; + tall = surfaceBounds[3]; +} + +void VGUI2Surface::GetProportionalBase( int &width, int &height ) +{ + width = 640; + height = 480; +} + +void VGUI2Surface::CalculateMouseVisible() +{ + if ( ignoreMouseVisCalc ) + return; + + needMouse = false; + needKB = false; + + for ( int i = 0; i < popups.getCount(); ++i ) + { + bool visible = vgui2::ipanel()->IsVisible( popups[i] ); + vgui2::VPANEL parent = vgui2::ipanel()->GetParent( popups[i] ); + + while ( parent != NULL && visible ) + { + if ( !vgui2::ipanel()->IsVisible( parent ) ) + { + visible = false; + break; + } + + parent = vgui2::ipanel()->GetParent( parent ); + } + + if ( !visible ) + continue; + + // TODO: Uncomment these once fully implemented to enable input capture + // needMouse = needMouse || vgui2::ipanel()->IsMouseInputEnabled( popups[i] ); + // needKB = needKB || vgui2::ipanel()->IsKeyBoardInputEnabled( popups[i] ); + } + + UnlockCursor(); + + if ( needMouse ) + { + SetCursor( vgui2::dc_arrow ); + } + else + { + SetCursor( vgui2::dc_none ); + LockCursor(); + } +} + +bool VGUI2Surface::NeedKBInput() +{ + return needKB; +} + +bool VGUI2Surface::HasCursorPosFunctions() +{ + return true; +} + +void VGUI2Surface::SurfaceGetCursorPos( int &x, int &y ) +{ + vgui_support::g_api->GetCursorPos( &x, &y ); +} + +void VGUI2Surface::SurfaceSetCursorPos( int x, int y ) +{ + // vgui_support::g_api->SetCursorPos( x, y ); +} + +void VGUI2Surface::DrawTexturedPolygon( vgui2::VGuiVertex *pVertices, int n ) +{ + // engineSurface->DrawTexturedPolygon( pVertices, n ); +} + +int VGUI2Surface::GetFontAscent( vgui2::HFont font, wchar_t wch ) +{ + // return some arbitrary number for now + return 0; +} + +void VGUI2Surface::SetAllowHTMLJavaScript( bool state ) +{ + allowJavaScript = state; +} + +void VGUI2Surface::SetLanguage( const char *pchLang ) +{ + if ( pchLang != nullptr ) + { + Q_strncpy( language, pchLang, sizeof( language ) ); + language[sizeof( language ) - 1] = '\0'; + } + else + { + Q_strcpy( language, "english" ); + } +} + +const char *VGUI2Surface::GetLanguage() +{ + return language; +} + +bool VGUI2Surface::DeleteTextureByID( int id ) +{ + return false; + // return engineSurface->DeleteTextureByID( id ); +} + +void VGUI2Surface::DrawUpdateRegionTextureBGRA( int nTextureID, int x, int y, const unsigned char *pchData, int wide, int tall ) +{ + // engineSurface->DrawUpdateRegionTextureBGRA( nTextureID, x, y, pchData, wide, tall ); +} + +void VGUI2Surface::DrawSetTextureBGRA( int id, const unsigned char *bgra, int wide, int tall ) +{ + // engineSurface->DrawSetTextureBGRA( id, bgra, wide, tall ); +} + +void VGUI2Surface::CreateBrowser( vgui2::VPANEL panel, IHTMLResponses *pBrowser, bool bPopupWindow, const char *pchUserAgentIdentifier ) +{ + if ( chromeController ) + chromeController->CreateBrowser( pBrowser, false, "Valve Half-Life" ); +} + +void VGUI2Surface::RemoveBrowser( vgui2::VPANEL panel, IHTMLResponses *pBrowser ) +{ + if ( chromeController ) + chromeController->RemoveBrowser( pBrowser ); +} + +IHTMLChromeController *VGUI2Surface::AccessChromeHTMLController() +{ + return chromeController; +} + +VGUI2Surface::VGUI2Surface() +{ + embeddedPanel = NULL; + restrictedPanel = NULL; + chromeController = nullptr; + allowJavaScript = false; + cursorLocked = false; + translateExtendedKeys = true; + ignoreMouseVisCalc = false; + currentCursor = vgui2::dc_none; + + // TODO: Change these to true once fully implemented to enable input capture + needKB = false; + needMouse = false; +} + +void VGUI2Surface::Init( vgui2::VPANEL _embeddedPanel, IHTMLChromeController *pChromeController ) +{ + SetEmbeddedPanel( _embeddedPanel ); + + chromeController = pChromeController; + if ( chromeController ) + { + chromeController->Init( "htmlcache", "htmlcookies" ); + chromeController->SetCefThreadTargetFrameRate( 60 ); + } +} + +void VGUI2Surface::SetScreenBounds( int x, int y, int wide, int tall ) +{ + surfaceBounds[0] = x; + surfaceBounds[1] = y; + surfaceBounds[2] = wide; + surfaceBounds[3] = tall; +} + +void VGUI2Surface::SetIgnoreMouseVisCalc( bool state ) +{ + ignoreMouseVisCalc = state; +} + +void VGUI2Surface::InternalSchemeSettingsTraverse( vgui2::VPANEL panel, bool forceApplySchemeSettings ) +{ + for ( int i = 0; i < vgui2::ipanel()->GetChildCount( panel ); ++i ) + { + vgui2::VPANEL child = vgui2::ipanel()->GetChild( panel, i ); + if ( forceApplySchemeSettings || vgui2::ipanel()->IsVisible( child ) ) + InternalSchemeSettingsTraverse( child, forceApplySchemeSettings ); + } + + vgui2::ipanel()->PerformApplySchemeSettings( panel ); +} + +void VGUI2Surface::InternalThinkTraverse( vgui2::VPANEL panel ) +{ + vgui2::ipanel()->Think( panel ); + + for ( int i = 0; i < vgui2::ipanel()->GetChildCount( panel ); ++i ) + { + vgui2::VPANEL child = vgui2::ipanel()->GetChild( panel, i ); + if ( vgui2::ipanel()->IsVisible( child ) ) + InternalThinkTraverse( child ); + } +} + +void VGUI2Surface::InternalSolveTraverse( vgui2::VPANEL panel ) +{ + vgui2::ipanel()->Solve( panel ); + + for ( int i = 0; i < vgui2::ipanel()->GetChildCount( panel ); ++i ) + { + vgui2::VPANEL child = vgui2::ipanel()->GetChild( panel, i ); + if ( vgui2::ipanel()->IsVisible( child ) ) + InternalSolveTraverse( child ); + } +} diff --git a/vgui2_surf.h b/vgui2_surf.h new file mode 100644 index 0000000..387170d --- /dev/null +++ b/vgui2_surf.h @@ -0,0 +1,160 @@ +/* +vgui2_surf.cpp - vgui2 surface header +Copyright (C) 2022 FWGS + +This program 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 3 of the License, or +(at your option) any later version. + +This program 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. + +In addition, as a special exception, the author gives permission +to link the code of this program with VGUI library developed by +Valve, L.L.C ("Valve"). You must obey the GNU General Public License +in all respects for all of the code used other than VGUI library. +If you modify this file, you may extend this exception to your +version of the file, but you are not obligated to do so. If +you do not wish to do so, delete this exception statement +from your version. + +*/ + +#ifndef VGUI2_SURFACE_H +#define VGUI2_SURFACE_H + +#include +#include +#include +#include + +class VGUI2Surface : public vgui2::ISurface +{ +public: + void Shutdown() override; + void RunFrame() override; + vgui2::VPANEL GetEmbeddedPanel() override; + void SetEmbeddedPanel( vgui2::VPANEL panel ) override; + void PushMakeCurrent( vgui2::VPANEL panel, bool useInsets ) override; + void PopMakeCurrent( vgui2::VPANEL panel ) override; + void DrawSetColor( int r, int g, int b, int a ) override; + void DrawSetColor( Color col ) override; + void DrawFilledRect( int x0, int y0, int x1, int y1 ) override; + void DrawOutlinedRect( int x0, int y0, int x1, int y1 ) override; + void DrawLine( int x0, int y0, int x1, int y1 ) override; + void DrawPolyLine( int *px, int *py, int numPoints ) override; + void DrawSetTextFont( vgui2::HFont font ) override; + void DrawSetTextColor( int r, int g, int b, int a ) override; + void DrawSetTextColor( Color col ) override; + void DrawSetTextPos( int x, int y ) override; + void DrawGetTextPos( int &x, int &y ) override; + void DrawPrintText( const wchar_t *text, int textLen ) override; + void DrawUnicodeChar( wchar_t wch ) override; + void DrawUnicodeCharAdd( wchar_t wch ) override; + void DrawFlushText() override; + vgui2::IHTML *CreateHTMLWindow( vgui2::IHTMLEvents *events, vgui2::VPANEL context ) override; + void PaintHTMLWindow( vgui2::IHTML *htmlwin ) override; + void DeleteHTMLWindow( vgui2::IHTML *htmlwin ) override; + void DrawSetTextureFile( int id, const char *filename, int hardwareFilter, bool forceReload ) override; + void DrawSetTextureRGBA( int id, const unsigned char *rgba, int wide, int tall, int hardwareFilter, bool forceReload ) override; + void DrawSetTexture( int id ) override; + void DrawGetTextureSize( int id, int &wide, int &tall ) override; + void DrawTexturedRect( int x0, int y0, int x1, int y1 ) override; + bool IsTextureIDValid( int id ) override; + int CreateNewTextureID( bool procedural ) override; + void GetScreenSize( int &wide, int &tall ) override; + void SetAsTopMost( vgui2::VPANEL panel, bool state ) override; + void BringToFront( vgui2::VPANEL panel ) override; + void SetForegroundWindow( vgui2::VPANEL panel ) override; + void SetPanelVisible( vgui2::VPANEL panel, bool state ) override; + void SetMinimized( vgui2::VPANEL panel, bool state ) override; + bool IsMinimized( vgui2::VPANEL panel ) override; + void FlashWindow( vgui2::VPANEL panel, bool state ) override; + void SetTitle( vgui2::VPANEL panel, const wchar_t *title ) override; + void SetAsToolBar( vgui2::VPANEL panel, bool state ) override; + void CreatePopup( vgui2::VPANEL panel, bool minimised, bool showTaskbarIcon, bool disabled, bool mouseInput, bool kbInput ) override; + void SwapBuffers( vgui2::VPANEL panel ) override; + void Invalidate( vgui2::VPANEL panel ) override; + void SetCursor( vgui2::HCursor cursor ) override; + bool IsCursorVisible() override; + void ApplyChanges() override; + bool IsWithin( int x, int y ) override; + bool HasFocus() override; + bool SupportsFeature( SurfaceFeature_e feature ) override; + void RestrictPaintToSinglePanel( vgui2::VPANEL panel ) override; + void SetModalPanel( vgui2::VPANEL panel ) override; + vgui2::VPANEL GetModalPanel() override; + void UnlockCursor() override; + void LockCursor() override; + void SetTranslateExtendedKeys( bool state ) override; + vgui2::VPANEL GetTopmostPopup() override; + void SetTopLevelFocus( vgui2::VPANEL panel ) override; + vgui2::HFont CreateFont() override; + bool AddGlyphSetToFont( vgui2::HFont font, const char *fontName, int tall, int weight, int blur, int scanlines, int flags, int lowRange, int highRange ) override; + bool AddCustomFontFile( const char *fontFileName ) override; + int GetFontTall( vgui2::HFont font ) override; + void GetCharABCwide( vgui2::HFont font, int ch, int &a, int &b, int &c ) override; + int GetCharacterWidth( vgui2::HFont font, int ch ) override; + void GetTextSize( vgui2::HFont font, const wchar_t *text, int &wide, int &tall ) override; + vgui2::VPANEL GetNotifyPanel() override; + void SetNotifyIcon( vgui2::VPANEL context, vgui2::HTexture icon, vgui2::VPANEL panelToReceiveMessages, const char *text ) override; + void PlaySound( const char *fileName ) override; + int GetPopupCount() override; + vgui2::VPANEL GetPopup( int index ) override; + bool ShouldPaintChildPanel( vgui2::VPANEL panel ) override; + bool RecreateContext( vgui2::VPANEL panel ) override; + void AddPanel( vgui2::VPANEL panel ) override; + void ReleasePanel( vgui2::VPANEL panel ) override; + void MovePopupToFront( vgui2::VPANEL panel ) override; + void MovePopupToBack( vgui2::VPANEL panel ) override; + void SolveTraverse( vgui2::VPANEL panel, bool forceApplySchemeSettings ) override; + void PaintTraverse( vgui2::VPANEL panel ) override; + void EnableMouseCapture( vgui2::VPANEL panel, bool state ) override; + void GetWorkspaceBounds( int &x, int &y, int &wide, int &tall ) override; + void GetAbsoluteWindowBounds( int &x, int &y, int &wide, int &tall ) override; + void GetProportionalBase( int &width, int &height ) override; + void CalculateMouseVisible() override; + bool NeedKBInput() override; + bool HasCursorPosFunctions() override; + void SurfaceGetCursorPos( int &x, int &y ) override; + void SurfaceSetCursorPos( int x, int y ) override; + void DrawTexturedPolygon( vgui2::VGuiVertex *pVertices, int n ) override; + int GetFontAscent( vgui2::HFont font, wchar_t wch ) override; + void SetAllowHTMLJavaScript( bool state ) override; + void SetLanguage( const char *pchLang ) override; + const char *GetLanguage() override; + bool DeleteTextureByID( int id ) override; + void DrawUpdateRegionTextureBGRA( int nTextureID, int x, int y, const unsigned char *pchData, int wide, int tall ) override; + void DrawSetTextureBGRA( int id, const unsigned char *bgra, int wide, int tall ) override; + void CreateBrowser( vgui2::VPANEL panel, IHTMLResponses *pBrowser, bool bPopupWindow, const char *pchUserAgentIdentifier ) override; + void RemoveBrowser( vgui2::VPANEL panel, IHTMLResponses *pBrowser ) override; + IHTMLChromeController *AccessChromeHTMLController() override; + + VGUI2Surface(); + void Init( vgui2::VPANEL _embeddedPanel, IHTMLChromeController *pChromeController ); + void SetScreenBounds( int x, int y, int wide, int tall ); + void SetIgnoreMouseVisCalc( bool state ); + void InternalSchemeSettingsTraverse( vgui2::VPANEL panel, bool forceApplySchemeSettings ); + void InternalThinkTraverse( vgui2::VPANEL panel ); + void InternalSolveTraverse( vgui2::VPANEL panel ); + +private: + vgui2::VPANEL embeddedPanel; + vgui2::VPANEL restrictedPanel; + char language[32]; + IHTMLChromeController *chromeController; + int surfaceBounds[4]; + vgui::Dar popups; + bool allowJavaScript; + bool needKB; + bool needMouse; + bool cursorLocked; + bool translateExtendedKeys; + bool ignoreMouseVisCalc; + vgui2::HCursor currentCursor; +}; + +#endif // VGUI2_SURFACE_H diff --git a/vgui_input.cpp b/vgui_input.cpp index 0a6ee74..232a2dc 100644 --- a/vgui_input.cpp +++ b/vgui_input.cpp @@ -27,9 +27,21 @@ from your version. #include "vgui_main.h" +bool VGUI2_UseVGUI1( void ); +void VGUI2_Key( VGUI_KeyAction action, VGUI_KeyCode code ); +void VGUI2_Mouse( VGUI_MouseAction action, int code ); +void VGUI2_MouseMove( int x, int y ); +void VGUI2_TextInput( const char *text ); + namespace vgui_support { void VGUI_Key(VGUI_KeyAction action, VGUI_KeyCode code) { + if ( !VGUI2_UseVGUI1() ) + { + VGUI2_Key( action, code ); + return; + } + App *pApp = App::getInstance(); if(!surface) return; @@ -51,6 +63,12 @@ void VGUI_Key(VGUI_KeyAction action, VGUI_KeyCode code) void VGUI_Mouse(VGUI_MouseAction action, int code) { + if ( !VGUI2_UseVGUI1() ) + { + VGUI2_Mouse( action, code ); + return; + } + App *pApp = App::getInstance(); if(!surface) return; @@ -76,6 +94,12 @@ void VGUI_Mouse(VGUI_MouseAction action, int code) void VGUI_MouseMove(int x, int y) { + if ( !VGUI2_UseVGUI1() ) + { + VGUI2_MouseMove( x, y ); + return; + } + App *pApp = App::getInstance(); //fprintf(stdout, "vgui_support: VGUI mouse move %d %d %p\n", x, y, surface); //fflush(stdout); @@ -86,6 +110,7 @@ void VGUI_MouseMove(int x, int y) void VGUI_TextInput(const char *text) { - // stub + if ( !VGUI2_UseVGUI1() ) + VGUI2_TextInput( text ); } } diff --git a/vgui_int.cpp b/vgui_int.cpp index 1506767..9f3faff 100644 --- a/vgui_int.cpp +++ b/vgui_int.cpp @@ -25,6 +25,12 @@ from your version. #include "vgui_main.h" #include "xash3d_types.h" + +void VGUI2_Startup( const char *clientlib, int width, int height ); +void VGUI2_Shutdown( void ); +bool VGUI2_UseVGUI1( void ); +void VGUI2_Paint( void ); + namespace vgui_support { vguiapi_t *g_api; @@ -33,10 +39,13 @@ Panel *rootpanel = NULL; CEngineSurface *surface = NULL; CEngineApp staticApp; -void VGui_Startup( int width, int height ) +void VGui_Startup( const char *clientlib, int width, int height ) { if( rootpanel ) { + // The second call to VGui_Startup will be after client.dll Initialize + // Only start client VGUI2 now + VGUI2_Startup( clientlib, width, height ); rootpanel->setSize( width, height ); return; } @@ -70,6 +79,8 @@ void VGui_Shutdown( void ) rootpanel = NULL; surface = NULL; + + VGUI2_Shutdown(); } void VGui_Paint( void ) @@ -89,13 +100,20 @@ void VGui_Paint( void ) rootpanel->getSize(w, h); EnableScissor( true ); - staticApp.externalTick (); + if ( VGUI2_UseVGUI1() ) + { + staticApp.externalTick (); - pVPanel->setBounds( 0, 0, w, h ); - pVPanel->repaint(); + pVPanel->setBounds( 0, 0, w, h ); + pVPanel->repaint(); - // paint everything - pVPanel->paintTraverse(); + // paint everything + pVPanel->paintTraverse(); + } + else + { + VGUI2_Paint(); + } EnableScissor( false ); } diff --git a/wscript b/wscript index 16a6a19..ab2c674 100644 --- a/wscript +++ b/wscript @@ -13,10 +13,14 @@ def options(opt): grp = opt.add_option_group('VGUI options') vgui_dev_path = os.path.join(opt.path.path_from(opt.root), 'vgui-dev') + vgui2_dev_path = os.path.join(opt.path.path_from(opt.root), 'vgui2-dev') grp.add_option('--vgui', action = 'store', dest = 'VGUI_DEV', default=vgui_dev_path, help = 'path to vgui-dev repo [default: %default]') + grp.add_option('--vgui2', action = 'store', dest = 'VGUI2_DEV', default=vgui2_dev_path, + help = 'path to vgui2-dev repo [default: %default]') + grp.add_option('--disable-vgui', action = 'store_true', dest = 'NO_VGUI', default = False, help = 'disable vgui_support [default: %default]') @@ -63,6 +67,7 @@ def configure(conf): conf.start_msg('Configuring VGUI by provided path') vgui_dev = conf.options.VGUI_DEV + vgui2_dev = conf.options.VGUI2_DEV if conf.env.DEST_OS == 'win32': conf.env.LIB_VGUI = ['vgui'] @@ -76,7 +81,7 @@ def configure(conf): conf.env.LDFLAGS_VGUI = [os.path.join(libpath, 'vgui.dylib')] else: conf.fatal('vgui is not supported on this OS: ' + conf.env.DEST_OS) - conf.env.INCLUDES_VGUI = [os.path.abspath(os.path.join(vgui_dev, 'include'))] + conf.env.INCLUDES_VGUI = [os.path.abspath(os.path.join(vgui_dev, 'include')), os.path.abspath(os.path.join(vgui2_dev, 'include'))] conf.env.HAVE_VGUI = 1 conf.end_msg('yes: {0}, {1}, {2}'.format(conf.env.LIB_VGUI, conf.env.LIBPATH_VGUI, conf.env.INCLUDES_VGUI)) @@ -100,7 +105,7 @@ def build(bld): if bld.env.NO_VGUI: return - libs = [ 'sdk_includes' ] + libs = [ 'public', 'filesystem_includes' ] # basic build: dedicated only, no dependencies if bld.env.DEST_OS != 'win32': @@ -109,6 +114,9 @@ def build(bld): libs.append('VGUI') source = bld.path.ant_glob(['*.cpp']) + + # FIXME: Glob using VGUI2_DEV instead + source += bld.path.ant_glob(['vgui2-dev/src/*.cpp']) includes = [ '.' ]