From 7bfc984dceaa7376118196fe8d35218589d48d59 Mon Sep 17 00:00:00 2001 From: Bien Pham Date: Thu, 3 Nov 2022 03:10:46 +0800 Subject: [PATCH 01/14] vgui_support: initial vgui2 support Counter-Strike 1.6 is loadable and playable with VGUI menus disabled. Currently no menu rendering is implemented and input is disabled. --- .gitmodules | 3 + vgui2-dev | 1 + vgui2_gameui.cpp | 92 ++++++ vgui2_int.cpp | 356 ++++++++++++++++++++++ vgui2_surf.cpp | 772 +++++++++++++++++++++++++++++++++++++++++++++++ vgui2_surf.h | 160 ++++++++++ vgui_input.cpp | 27 +- vgui_int.cpp | 30 +- wscript | 12 +- 9 files changed, 1444 insertions(+), 9 deletions(-) create mode 160000 vgui2-dev create mode 100644 vgui2_gameui.cpp create mode 100644 vgui2_int.cpp create mode 100644 vgui2_surf.cpp create mode 100644 vgui2_surf.h 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..5f3f072 --- /dev/null +++ b/vgui2-dev @@ -0,0 +1 @@ +Subproject commit 5f3f0721c5db29664db7d5a3fbed4b3d9f74553e diff --git a/vgui2_gameui.cpp b/vgui2_gameui.cpp new file mode 100644 index 0000000..8543e34 --- /dev/null +++ b/vgui2_gameui.cpp @@ -0,0 +1,92 @@ +/* +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 "IGameUIFuncs.h" +#include + +namespace vgui_support +{ +extern vguiapi_t *g_api; +}; + +class GameUIFuncs : public IGameUIFuncs +{ +public: + virtual bool IsKeyDown( const char *keyname, bool &isdown ); + virtual const char *Key_NameForKey( int keynum ); + virtual const char *Key_BindingForKey( int keynum ); + virtual vgui2::KeyCode GetVGUI2KeyCodeForBind( const char *bind ); + virtual void GetVideoModes( vmode_t **liststart, int *count ); + virtual void GetCurrentVideoMode( int *wide, int *tall, int *bpp ); + virtual void GetCurrentRenderer( char *name, int namelen, int *windowed, int *hdmodels, int *addons_folder, int *vid_level ); + virtual bool IsConnectedToVACSecureServer(); + virtual int Key_KeyStringToKeyNum( const char *pchKey ); +}; + +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; +} + +EXPOSE_SINGLE_INTERFACE( GameUIFuncs, IGameUIFuncs, VENGINE_GAMEUIFUNCS_VERSION ); diff --git a/vgui2_int.cpp b/vgui2_int.cpp new file mode 100644 index 0000000..c263b75 --- /dev/null +++ b/vgui2_int.cpp @@ -0,0 +1,356 @@ +/* +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 +#include +#include +#include +#include + +class RootPanel : public vgui2::Panel +{ +public: + RootPanel( vgui2::Panel *parent, const char *panelName ) : vgui2::Panel( parent, panelName ) { } + + virtual vgui2::VPANEL IsWithinTraverse( int x, int y, bool traversePopups ) + { + 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 ) { } + virtual void Initialize( CreateInterfaceFn *factories, int count ); + virtual void Start( IEngineSurface *engineSurface, int interfaceVersion ); + virtual void Shutdown(); + virtual int Key_Event( int down, int keynum, const char *pszCurrentBinding ); + virtual void CallEngineSurfaceAppHandler( void *event, void *userData ); + virtual void Paint( int x, int y, int right, int bottom ); + virtual void HideGameUI(); + virtual void ActivateGameUI(); + virtual void HideConsole(); + virtual void ShowConsole(); + +private: + static constexpr int MAX_NUM_FACTORIES = 6; + + int initialized; + CreateInterfaceFn factoryList[MAX_NUM_FACTORIES]; + int numFactories; + CSysModule *vgui2Module; + CSysModule *chromeModule; +}; + +static RootPanel *rootPanel; +static IClientVGUI *clientVGUI; +static VGUI2Surface *vgui2Surface; +static CSysModule *fileSystemModule; +static IVFileSystem009 *fileSystem; +static IBaseUI *baseUI; + +static CSysModule *LoadModule( const char *module ) +{ + static char szPath[MAX_OSPATH]; + + if ( fileSystem == nullptr ) + return Sys_LoadModule( module ); + + if ( fileSystem->GetLocalPath( module, szPath, sizeof(szPath) ) == nullptr ) + return nullptr; + + return Sys_LoadModule( szPath ); +} + +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++] = Sys_GetFactory( vgui2Module ); + factoryList[numFactories++] = factories[1]; + factoryList[numFactories++] = Sys_GetFactory( chromeModule ); + + if ( factories[2] != nullptr ) + { + factoryList[numFactories++] = factories[2]; + clientVGUI = (IClientVGUI *)factoryList[4]( VCLIENTVGUI_INTERFACE_VERSION, nullptr ); + } + + vgui2::InitializeVGui2Interfaces( "BaseUI", factoryList, numFactories ); + vgui2Surface = (VGUI2Surface *)vgui2::surface(); + + initialized = 1; +} + +void BaseUI::Start( IEngineSurface *engineSurface, int interfaceVersion ) +{ + if ( !initialized ) + return; + + rootPanel = new RootPanel( nullptr, "RootPanel" ); + rootPanel->SetCursor( vgui2::dc_none ); + rootPanel->SetBounds( 0, 0, 40, 30 ); + 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(); + + Sys_UnloadModule( chromeModule ); + chromeModule = nullptr; + Sys_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() +{ +} + +void VGUI2_Startup( const char *clientlib, int width, int height ) +{ + if ( baseUI == nullptr ) + { + fileSystemModule = LoadModule( "filesystem_stdio." OS_LIB_EXT ); + auto fileSystemFactory = Sys_GetFactory( fileSystemModule ); + fileSystem = (IVFileSystem009 *)fileSystemFactory( "VFileSystem009", nullptr ); + + CreateInterfaceFn factories[3]; + factories[0] = Sys_GetFactoryThis(); + factories[1] = fileSystemFactory; + factories[2] = Sys_GetFactory( LoadModule( clientlib ) ); + + baseUI = (IBaseUI *)factories[0]( BASEUI_INTERFACE_VERSION, nullptr ); + baseUI->Initialize( factories, 3 ); + baseUI->Start( nullptr, 0 ); + } + + rootPanel->SetBounds( 0, 0, width, height ); +} + +void VGUI2_Shutdown( void ) +{ + if ( baseUI == nullptr ) + return; + + baseUI->Shutdown(); + baseUI = nullptr; + Sys_UnloadModule( fileSystemModule ); + 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 ( baseUI == 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 ( baseUI == 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 ( baseUI == 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 ( baseUI == nullptr ) + return; + + vgui2::inputinternal()->InternalCursorMoved( x, y ); +} + +void VGUI2_TextInput( const char *text ) +{ + for ( const char *c = text; *c; c++ ) + vgui2::inputinternal()->InternalKeyTyped( *c ); +} + +EXPOSE_SINGLE_INTERFACE( BaseUI, IBaseUI, BASEUI_INTERFACE_VERSION ); diff --git a/vgui2_surf.cpp b/vgui2_surf.cpp new file mode 100644 index 0000000..03cf40a --- /dev/null +++ b/vgui2_surf.cpp @@ -0,0 +1,772 @@ +/* +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 ); + } +} + +EXPOSE_SINGLE_INTERFACE( VGUI2Surface, ISurface, VGUI_SURFACE_INTERFACE_VERSION ); diff --git a/vgui2_surf.h b/vgui2_surf.h new file mode 100644 index 0000000..750c6b4 --- /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: + virtual void Shutdown(); + virtual void RunFrame(); + virtual vgui2::VPANEL GetEmbeddedPanel(); + virtual void SetEmbeddedPanel( vgui2::VPANEL panel ); + virtual void PushMakeCurrent( vgui2::VPANEL panel, bool useInsets ); + virtual void PopMakeCurrent( vgui2::VPANEL panel ); + virtual void DrawSetColor( int r, int g, int b, int a ); + virtual void DrawSetColor( Color col ); + virtual void DrawFilledRect( int x0, int y0, int x1, int y1 ); + virtual void DrawOutlinedRect( int x0, int y0, int x1, int y1 ); + virtual void DrawLine( int x0, int y0, int x1, int y1 ); + virtual void DrawPolyLine( int *px, int *py, int numPoints ); + virtual void DrawSetTextFont( vgui2::HFont font ); + virtual void DrawSetTextColor( int r, int g, int b, int a ); + virtual void DrawSetTextColor( Color col ); + virtual void DrawSetTextPos( int x, int y ); + virtual void DrawGetTextPos( int &x, int &y ); + virtual void DrawPrintText( const wchar_t *text, int textLen ); + virtual void DrawUnicodeChar( wchar_t wch ); + virtual void DrawUnicodeCharAdd( wchar_t wch ); + virtual void DrawFlushText(); + virtual vgui2::IHTML *CreateHTMLWindow( vgui2::IHTMLEvents *events, vgui2::VPANEL context ); + virtual void PaintHTMLWindow( vgui2::IHTML *htmlwin ); + virtual void DeleteHTMLWindow( vgui2::IHTML *htmlwin ); + virtual void DrawSetTextureFile( int id, const char *filename, int hardwareFilter, bool forceReload ); + virtual void DrawSetTextureRGBA( int id, const unsigned char *rgba, int wide, int tall, int hardwareFilter, bool forceReload ); + virtual void DrawSetTexture( int id ); + virtual void DrawGetTextureSize( int id, int &wide, int &tall ); + virtual void DrawTexturedRect( int x0, int y0, int x1, int y1 ); + virtual bool IsTextureIDValid( int id ); + virtual int CreateNewTextureID( bool procedural ); + virtual void GetScreenSize( int &wide, int &tall ); + virtual void SetAsTopMost( vgui2::VPANEL panel, bool state ); + virtual void BringToFront( vgui2::VPANEL panel ); + virtual void SetForegroundWindow( vgui2::VPANEL panel ); + virtual void SetPanelVisible( vgui2::VPANEL panel, bool state ); + virtual void SetMinimized( vgui2::VPANEL panel, bool state ); + virtual bool IsMinimized( vgui2::VPANEL panel ); + virtual void FlashWindow( vgui2::VPANEL panel, bool state ); + virtual void SetTitle( vgui2::VPANEL panel, const wchar_t *title ); + virtual void SetAsToolBar( vgui2::VPANEL panel, bool state ); + virtual void CreatePopup( vgui2::VPANEL panel, bool minimised, bool showTaskbarIcon, bool disabled, bool mouseInput, bool kbInput ); + virtual void SwapBuffers( vgui2::VPANEL panel ); + virtual void Invalidate( vgui2::VPANEL panel ); + virtual void SetCursor( vgui2::HCursor cursor ); + virtual bool IsCursorVisible(); + virtual void ApplyChanges(); + virtual bool IsWithin( int x, int y ); + virtual bool HasFocus(); + virtual bool SupportsFeature( SurfaceFeature_e feature ); + virtual void RestrictPaintToSinglePanel( vgui2::VPANEL panel ); + virtual void SetModalPanel( vgui2::VPANEL panel ); + virtual vgui2::VPANEL GetModalPanel(); + virtual void UnlockCursor(); + virtual void LockCursor(); + virtual void SetTranslateExtendedKeys( bool state ); + virtual vgui2::VPANEL GetTopmostPopup(); + virtual void SetTopLevelFocus( vgui2::VPANEL panel ); + virtual vgui2::HFont CreateFont(); + virtual bool AddGlyphSetToFont( vgui2::HFont font, const char *fontName, int tall, int weight, int blur, int scanlines, int flags, int lowRange, int highRange ); + virtual bool AddCustomFontFile( const char *fontFileName ); + virtual int GetFontTall( vgui2::HFont font ); + virtual void GetCharABCwide( vgui2::HFont font, int ch, int &a, int &b, int &c ); + virtual int GetCharacterWidth( vgui2::HFont font, int ch ); + virtual void GetTextSize( vgui2::HFont font, const wchar_t *text, int &wide, int &tall ); + virtual vgui2::VPANEL GetNotifyPanel(); + virtual void SetNotifyIcon( vgui2::VPANEL context, vgui2::HTexture icon, vgui2::VPANEL panelToReceiveMessages, const char *text ); + virtual void PlaySound( const char *fileName ); + virtual int GetPopupCount(); + virtual vgui2::VPANEL GetPopup( int index ); + virtual bool ShouldPaintChildPanel( vgui2::VPANEL panel ); + virtual bool RecreateContext( vgui2::VPANEL panel ); + virtual void AddPanel( vgui2::VPANEL panel ); + virtual void ReleasePanel( vgui2::VPANEL panel ); + virtual void MovePopupToFront( vgui2::VPANEL panel ); + virtual void MovePopupToBack( vgui2::VPANEL panel ); + virtual void SolveTraverse( vgui2::VPANEL panel, bool forceApplySchemeSettings ); + virtual void PaintTraverse( vgui2::VPANEL panel ); + virtual void EnableMouseCapture( vgui2::VPANEL panel, bool state ); + virtual void GetWorkspaceBounds( int &x, int &y, int &wide, int &tall ); + virtual void GetAbsoluteWindowBounds( int &x, int &y, int &wide, int &tall ); + virtual void GetProportionalBase( int &width, int &height ); + virtual void CalculateMouseVisible(); + virtual bool NeedKBInput(); + virtual bool HasCursorPosFunctions(); + virtual void SurfaceGetCursorPos( int &x, int &y ); + virtual void SurfaceSetCursorPos( int x, int y ); + virtual void DrawTexturedPolygon( vgui2::VGuiVertex *pVertices, int n ); + virtual int GetFontAscent( vgui2::HFont font, wchar_t wch ); + virtual void SetAllowHTMLJavaScript( bool state ); + virtual void SetLanguage( const char *pchLang ); + virtual const char *GetLanguage(); + virtual bool DeleteTextureByID( int id ); + virtual void DrawUpdateRegionTextureBGRA( int nTextureID, int x, int y, const unsigned char *pchData, int wide, int tall ); + virtual void DrawSetTextureBGRA( int id, const unsigned char *bgra, int wide, int tall ); + virtual void CreateBrowser( vgui2::VPANEL panel, IHTMLResponses *pBrowser, bool bPopupWindow, const char *pchUserAgentIdentifier ); + virtual void RemoveBrowser( vgui2::VPANEL panel, IHTMLResponses *pBrowser ); + virtual IHTMLChromeController *AccessChromeHTMLController(); + + 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 = [ '.' ] From 48a22e9f5524e03746d1299fbf712912a72671a9 Mon Sep 17 00:00:00 2001 From: Bien Pham Date: Thu, 3 Nov 2022 18:46:48 +0800 Subject: [PATCH 02/14] vgui2: avoid using valve interface header --- vgui2-dev | 2 +- vgui2_gameui.cpp | 18 +------- vgui2_gameui.h | 45 ++++++++++++++++++++ vgui2_int.cpp | 104 ++++++++++++++++++++++++++++------------------- vgui2_surf.cpp | 2 - 5 files changed, 110 insertions(+), 61 deletions(-) create mode 100644 vgui2_gameui.h diff --git a/vgui2-dev b/vgui2-dev index 5f3f072..e55d524 160000 --- a/vgui2-dev +++ b/vgui2-dev @@ -1 +1 @@ -Subproject commit 5f3f0721c5db29664db7d5a3fbed4b3d9f74553e +Subproject commit e55d52447838a0db469bc182cef24fb695164381 diff --git a/vgui2_gameui.cpp b/vgui2_gameui.cpp index 8543e34..6d7e79c 100644 --- a/vgui2_gameui.cpp +++ b/vgui2_gameui.cpp @@ -23,7 +23,7 @@ from your version. */ -#include "IGameUIFuncs.h" +#include "vgui2_gameui.h" #include namespace vgui_support @@ -31,20 +31,6 @@ namespace vgui_support extern vguiapi_t *g_api; }; -class GameUIFuncs : public IGameUIFuncs -{ -public: - virtual bool IsKeyDown( const char *keyname, bool &isdown ); - virtual const char *Key_NameForKey( int keynum ); - virtual const char *Key_BindingForKey( int keynum ); - virtual vgui2::KeyCode GetVGUI2KeyCodeForBind( const char *bind ); - virtual void GetVideoModes( vmode_t **liststart, int *count ); - virtual void GetCurrentVideoMode( int *wide, int *tall, int *bpp ); - virtual void GetCurrentRenderer( char *name, int namelen, int *windowed, int *hdmodels, int *addons_folder, int *vid_level ); - virtual bool IsConnectedToVACSecureServer(); - virtual int Key_KeyStringToKeyNum( const char *pchKey ); -}; - bool GameUIFuncs::IsKeyDown( const char *keyname, bool &isdown ) { isdown = false; @@ -88,5 +74,3 @@ int GameUIFuncs::Key_KeyStringToKeyNum( const char *pchKey ) { return 0; } - -EXPOSE_SINGLE_INTERFACE( GameUIFuncs, IGameUIFuncs, VENGINE_GAMEUIFUNCS_VERSION ); diff --git a/vgui2_gameui.h b/vgui2_gameui.h new file mode 100644 index 0000000..5f9064c --- /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: + virtual bool IsKeyDown( const char *keyname, bool &isdown ); + virtual const char *Key_NameForKey( int keynum ); + virtual const char *Key_BindingForKey( int keynum ); + virtual vgui2::KeyCode GetVGUI2KeyCodeForBind( const char *bind ); + virtual void GetVideoModes( vmode_t **liststart, int *count ); + virtual void GetCurrentVideoMode( int *wide, int *tall, int *bpp ); + virtual void GetCurrentRenderer( char *name, int namelen, int *windowed, int *hdmodels, int *addons_folder, int *vid_level ); + virtual bool IsConnectedToVACSecureServer(); + virtual int Key_KeyStringToKeyNum( const char *pchKey ); +}; + +#endif // VGUI2_GAMEUI_H diff --git a/vgui2_int.cpp b/vgui2_int.cpp index c263b75..12eede8 100644 --- a/vgui2_int.cpp +++ b/vgui2_int.cpp @@ -26,12 +26,18 @@ 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: @@ -68,28 +74,32 @@ class BaseUI : public IBaseUI int initialized; CreateInterfaceFn factoryList[MAX_NUM_FACTORIES]; int numFactories; - CSysModule *vgui2Module; - CSysModule *chromeModule; + void *vgui2Module; + void *chromeModule; }; static RootPanel *rootPanel; static IClientVGUI *clientVGUI; -static VGUI2Surface *vgui2Surface; -static CSysModule *fileSystemModule; +static void *fileSystemModule; static IVFileSystem009 *fileSystem; -static IBaseUI *baseUI; -static CSysModule *LoadModule( const char *module ) +static VGUI2Surface vgui2Surface; +static BaseUI baseUI; +static GameUIFuncs gameUIFuncs; + +static inline void *LoadModule( const char *module ) { - static char szPath[MAX_OSPATH]; - - if ( fileSystem == nullptr ) - return Sys_LoadModule( module ); + return vgui_support::g_api->COM_LoadLibrary( module, false, false ); +} - if ( fileSystem->GetLocalPath( module, szPath, sizeof(szPath) ) == nullptr ) - return nullptr; +static inline CreateInterfaceFn GetFactory( void *module ) +{ + return (CreateInterfaceFn)vgui_support::g_api->COM_GetProcAddress( module, "CreateInterface" ); +} - return Sys_LoadModule( szPath ); +static inline void UnloadModule( void *module ) +{ + vgui_support::g_api->COM_FreeLibrary( module ); } void BaseUI::Initialize( CreateInterfaceFn *factories, int count ) @@ -101,9 +111,9 @@ void BaseUI::Initialize( CreateInterfaceFn *factories, int count ) chromeModule = LoadModule( "chromehtml." OS_LIB_EXT ); factoryList[numFactories++] = factories[0]; - factoryList[numFactories++] = Sys_GetFactory( vgui2Module ); + factoryList[numFactories++] = GetFactory( vgui2Module ); factoryList[numFactories++] = factories[1]; - factoryList[numFactories++] = Sys_GetFactory( chromeModule ); + factoryList[numFactories++] = GetFactory( chromeModule ); if ( factories[2] != nullptr ) { @@ -112,7 +122,6 @@ void BaseUI::Initialize( CreateInterfaceFn *factories, int count ) } vgui2::InitializeVGui2Interfaces( "BaseUI", factoryList, numFactories ); - vgui2Surface = (VGUI2Surface *)vgui2::surface(); initialized = 1; } @@ -132,8 +141,8 @@ void BaseUI::Start( IEngineSurface *engineSurface, int interfaceVersion ) rootPanel->SetZPos( 0 ); auto chromeController = (IHTMLChromeController *)factoryList[3]( CHROME_HTML_CONTROLLER_INTERFACE_VERSION, nullptr ); - vgui2Surface->Init( rootPanel->GetVPanel(), chromeController ); - vgui2Surface->SetIgnoreMouseVisCalc( true ); + vgui2Surface.Init( rootPanel->GetVPanel(), chromeController ); + vgui2Surface.SetIgnoreMouseVisCalc( true ); vgui2::scheme()->LoadSchemeFromFile( "resource/trackerscheme.res", "BaseUI" ); @@ -165,7 +174,7 @@ void BaseUI::Start( IEngineSurface *engineSurface, int interfaceVersion ) clientVGUI->SetParent( rootPanel->GetVPanel() ); } - vgui2Surface->SetIgnoreMouseVisCalc( false ); + vgui2Surface.SetIgnoreMouseVisCalc( false ); } void BaseUI::Shutdown() @@ -185,9 +194,9 @@ void BaseUI::Shutdown() vgui2::system()->SaveUserConfigFile(); vgui2::surface()->Shutdown(); - Sys_UnloadModule( chromeModule ); + UnloadModule( chromeModule ); chromeModule = nullptr; - Sys_UnloadModule( vgui2Module ); + UnloadModule( vgui2Module ); vgui2Module = nullptr; } @@ -213,7 +222,7 @@ void BaseUI::Paint( int x, int y, int right, int bottom ) return; vgui2::ivgui()->RunFrame(); - vgui2Surface->SetScreenBounds( x, y, right - x, bottom - y ); + vgui2Surface.SetScreenBounds( x, y, right - x, bottom - y ); rootPanel->SetBounds( 0, 0, right, bottom ); rootPanel->Repaint(); vgui2::surface()->PaintTraverse( panel ); @@ -236,22 +245,38 @@ 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 ( baseUI == nullptr ) + if ( rootPanel == nullptr ) { fileSystemModule = LoadModule( "filesystem_stdio." OS_LIB_EXT ); - auto fileSystemFactory = Sys_GetFactory( fileSystemModule ); + auto fileSystemFactory = GetFactory( fileSystemModule ); fileSystem = (IVFileSystem009 *)fileSystemFactory( "VFileSystem009", nullptr ); CreateInterfaceFn factories[3]; - factories[0] = Sys_GetFactoryThis(); + factories[0] = CreateInterface; factories[1] = fileSystemFactory; - factories[2] = Sys_GetFactory( LoadModule( clientlib ) ); + factories[2] = GetFactory( LoadModule( clientlib ) ); - baseUI = (IBaseUI *)factories[0]( BASEUI_INTERFACE_VERSION, nullptr ); - baseUI->Initialize( factories, 3 ); - baseUI->Start( nullptr, 0 ); + baseUI.Initialize( factories, 3 ); + baseUI.Start( nullptr, 0 ); } rootPanel->SetBounds( 0, 0, width, height ); @@ -259,12 +284,11 @@ void VGUI2_Startup( const char *clientlib, int width, int height ) void VGUI2_Shutdown( void ) { - if ( baseUI == nullptr ) + if ( rootPanel == nullptr ) return; - baseUI->Shutdown(); - baseUI = nullptr; - Sys_UnloadModule( fileSystemModule ); + baseUI.Shutdown(); + UnloadModule( fileSystemModule ); fileSystemModule = nullptr; fileSystem = nullptr; } @@ -284,20 +308,20 @@ bool VGUI2_UseVGUI1( void ) void VGUI2_Paint( void ) { - if ( baseUI == nullptr ) + if ( rootPanel == nullptr ) return; int wide, tall; VGUI2_ScreenSize( wide, tall ); - baseUI->Paint( 0, 0, wide, tall ); + baseUI.Paint( 0, 0, wide, tall ); } void VGUI2_Key( VGUI_KeyAction action, VGUI_KeyCode code ) { - if ( baseUI == nullptr ) + if ( rootPanel == nullptr ) return; - if ( !baseUI->Key_Event( action == KA_PRESSED, code + 1, "" ) ) + if ( !baseUI.Key_Event( action == KA_PRESSED, code + 1, "" ) ) return; switch ( action ) @@ -316,7 +340,7 @@ void VGUI2_Key( VGUI_KeyAction action, VGUI_KeyCode code ) void VGUI2_Mouse( VGUI_MouseAction action, int code ) { - if ( baseUI == nullptr ) + if ( rootPanel == nullptr ) return; if ( !vgui2::surface()->IsCursorVisible() ) @@ -341,7 +365,7 @@ void VGUI2_Mouse( VGUI_MouseAction action, int code ) void VGUI2_MouseMove( int x, int y ) { - if ( baseUI == nullptr ) + if ( rootPanel == nullptr ) return; vgui2::inputinternal()->InternalCursorMoved( x, y ); @@ -352,5 +376,3 @@ void VGUI2_TextInput( const char *text ) for ( const char *c = text; *c; c++ ) vgui2::inputinternal()->InternalKeyTyped( *c ); } - -EXPOSE_SINGLE_INTERFACE( BaseUI, IBaseUI, BASEUI_INTERFACE_VERSION ); diff --git a/vgui2_surf.cpp b/vgui2_surf.cpp index 03cf40a..4fc1ece 100644 --- a/vgui2_surf.cpp +++ b/vgui2_surf.cpp @@ -768,5 +768,3 @@ void VGUI2Surface::InternalSolveTraverse( vgui2::VPANEL panel ) InternalSolveTraverse( child ); } } - -EXPOSE_SINGLE_INTERFACE( VGUI2Surface, ISurface, VGUI_SURFACE_INTERFACE_VERSION ); From 004c70b4d586e69d75f027fa2d3d5dd067c8743e Mon Sep 17 00:00:00 2001 From: Bien Pham Date: Thu, 3 Nov 2022 23:35:17 +0800 Subject: [PATCH 03/14] vgui2: update vgui2-dev --- vgui2-dev | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vgui2-dev b/vgui2-dev index e55d524..5fd52f3 160000 --- a/vgui2-dev +++ b/vgui2-dev @@ -1 +1 @@ -Subproject commit e55d52447838a0db469bc182cef24fb695164381 +Subproject commit 5fd52f39ec87117ed10a538da949ba61e52ffd9a From d3b2e4e450f6bb24351e65488bc1c79e81c9cf09 Mon Sep 17 00:00:00 2001 From: Bien Pham Date: Sat, 5 Nov 2022 19:33:11 +0800 Subject: [PATCH 04/14] vgui2: use override keyword for virtual methods --- vgui2_gameui.h | 18 ++--- vgui2_int.cpp | 22 +++--- vgui2_surf.h | 196 ++++++++++++++++++++++++------------------------- 3 files changed, 118 insertions(+), 118 deletions(-) diff --git a/vgui2_gameui.h b/vgui2_gameui.h index 5f9064c..f8010b9 100644 --- a/vgui2_gameui.h +++ b/vgui2_gameui.h @@ -31,15 +31,15 @@ from your version. class GameUIFuncs : public IGameUIFuncs { public: - virtual bool IsKeyDown( const char *keyname, bool &isdown ); - virtual const char *Key_NameForKey( int keynum ); - virtual const char *Key_BindingForKey( int keynum ); - virtual vgui2::KeyCode GetVGUI2KeyCodeForBind( const char *bind ); - virtual void GetVideoModes( vmode_t **liststart, int *count ); - virtual void GetCurrentVideoMode( int *wide, int *tall, int *bpp ); - virtual void GetCurrentRenderer( char *name, int namelen, int *windowed, int *hdmodels, int *addons_folder, int *vid_level ); - virtual bool IsConnectedToVACSecureServer(); - virtual int Key_KeyStringToKeyNum( const char *pchKey ); + 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 index 12eede8..508ba41 100644 --- a/vgui2_int.cpp +++ b/vgui2_int.cpp @@ -43,7 +43,7 @@ class RootPanel : public vgui2::Panel public: RootPanel( vgui2::Panel *parent, const char *panelName ) : vgui2::Panel( parent, panelName ) { } - virtual vgui2::VPANEL IsWithinTraverse( int x, int y, bool traversePopups ) + vgui2::VPANEL IsWithinTraverse( int x, int y, bool traversePopups ) override { auto panel = vgui2::Panel::IsWithinTraverse( x, y, traversePopups ); if ( panel == GetVPanel() ) @@ -57,16 +57,16 @@ class BaseUI : public IBaseUI { public: BaseUI() : initialized( 0 ), numFactories( 0 ) { } - virtual void Initialize( CreateInterfaceFn *factories, int count ); - virtual void Start( IEngineSurface *engineSurface, int interfaceVersion ); - virtual void Shutdown(); - virtual int Key_Event( int down, int keynum, const char *pszCurrentBinding ); - virtual void CallEngineSurfaceAppHandler( void *event, void *userData ); - virtual void Paint( int x, int y, int right, int bottom ); - virtual void HideGameUI(); - virtual void ActivateGameUI(); - virtual void HideConsole(); - virtual void ShowConsole(); + void Initialize( CreateInterfaceFn *factories, int count ) override; + void Start( IEngineSurface *engineSurface, int interfaceVersion ) 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; diff --git a/vgui2_surf.h b/vgui2_surf.h index 750c6b4..387170d 100644 --- a/vgui2_surf.h +++ b/vgui2_surf.h @@ -34,104 +34,104 @@ from your version. class VGUI2Surface : public vgui2::ISurface { public: - virtual void Shutdown(); - virtual void RunFrame(); - virtual vgui2::VPANEL GetEmbeddedPanel(); - virtual void SetEmbeddedPanel( vgui2::VPANEL panel ); - virtual void PushMakeCurrent( vgui2::VPANEL panel, bool useInsets ); - virtual void PopMakeCurrent( vgui2::VPANEL panel ); - virtual void DrawSetColor( int r, int g, int b, int a ); - virtual void DrawSetColor( Color col ); - virtual void DrawFilledRect( int x0, int y0, int x1, int y1 ); - virtual void DrawOutlinedRect( int x0, int y0, int x1, int y1 ); - virtual void DrawLine( int x0, int y0, int x1, int y1 ); - virtual void DrawPolyLine( int *px, int *py, int numPoints ); - virtual void DrawSetTextFont( vgui2::HFont font ); - virtual void DrawSetTextColor( int r, int g, int b, int a ); - virtual void DrawSetTextColor( Color col ); - virtual void DrawSetTextPos( int x, int y ); - virtual void DrawGetTextPos( int &x, int &y ); - virtual void DrawPrintText( const wchar_t *text, int textLen ); - virtual void DrawUnicodeChar( wchar_t wch ); - virtual void DrawUnicodeCharAdd( wchar_t wch ); - virtual void DrawFlushText(); - virtual vgui2::IHTML *CreateHTMLWindow( vgui2::IHTMLEvents *events, vgui2::VPANEL context ); - virtual void PaintHTMLWindow( vgui2::IHTML *htmlwin ); - virtual void DeleteHTMLWindow( vgui2::IHTML *htmlwin ); - virtual void DrawSetTextureFile( int id, const char *filename, int hardwareFilter, bool forceReload ); - virtual void DrawSetTextureRGBA( int id, const unsigned char *rgba, int wide, int tall, int hardwareFilter, bool forceReload ); - virtual void DrawSetTexture( int id ); - virtual void DrawGetTextureSize( int id, int &wide, int &tall ); - virtual void DrawTexturedRect( int x0, int y0, int x1, int y1 ); - virtual bool IsTextureIDValid( int id ); - virtual int CreateNewTextureID( bool procedural ); - virtual void GetScreenSize( int &wide, int &tall ); - virtual void SetAsTopMost( vgui2::VPANEL panel, bool state ); - virtual void BringToFront( vgui2::VPANEL panel ); - virtual void SetForegroundWindow( vgui2::VPANEL panel ); - virtual void SetPanelVisible( vgui2::VPANEL panel, bool state ); - virtual void SetMinimized( vgui2::VPANEL panel, bool state ); - virtual bool IsMinimized( vgui2::VPANEL panel ); - virtual void FlashWindow( vgui2::VPANEL panel, bool state ); - virtual void SetTitle( vgui2::VPANEL panel, const wchar_t *title ); - virtual void SetAsToolBar( vgui2::VPANEL panel, bool state ); - virtual void CreatePopup( vgui2::VPANEL panel, bool minimised, bool showTaskbarIcon, bool disabled, bool mouseInput, bool kbInput ); - virtual void SwapBuffers( vgui2::VPANEL panel ); - virtual void Invalidate( vgui2::VPANEL panel ); - virtual void SetCursor( vgui2::HCursor cursor ); - virtual bool IsCursorVisible(); - virtual void ApplyChanges(); - virtual bool IsWithin( int x, int y ); - virtual bool HasFocus(); - virtual bool SupportsFeature( SurfaceFeature_e feature ); - virtual void RestrictPaintToSinglePanel( vgui2::VPANEL panel ); - virtual void SetModalPanel( vgui2::VPANEL panel ); - virtual vgui2::VPANEL GetModalPanel(); - virtual void UnlockCursor(); - virtual void LockCursor(); - virtual void SetTranslateExtendedKeys( bool state ); - virtual vgui2::VPANEL GetTopmostPopup(); - virtual void SetTopLevelFocus( vgui2::VPANEL panel ); - virtual vgui2::HFont CreateFont(); - virtual bool AddGlyphSetToFont( vgui2::HFont font, const char *fontName, int tall, int weight, int blur, int scanlines, int flags, int lowRange, int highRange ); - virtual bool AddCustomFontFile( const char *fontFileName ); - virtual int GetFontTall( vgui2::HFont font ); - virtual void GetCharABCwide( vgui2::HFont font, int ch, int &a, int &b, int &c ); - virtual int GetCharacterWidth( vgui2::HFont font, int ch ); - virtual void GetTextSize( vgui2::HFont font, const wchar_t *text, int &wide, int &tall ); - virtual vgui2::VPANEL GetNotifyPanel(); - virtual void SetNotifyIcon( vgui2::VPANEL context, vgui2::HTexture icon, vgui2::VPANEL panelToReceiveMessages, const char *text ); - virtual void PlaySound( const char *fileName ); - virtual int GetPopupCount(); - virtual vgui2::VPANEL GetPopup( int index ); - virtual bool ShouldPaintChildPanel( vgui2::VPANEL panel ); - virtual bool RecreateContext( vgui2::VPANEL panel ); - virtual void AddPanel( vgui2::VPANEL panel ); - virtual void ReleasePanel( vgui2::VPANEL panel ); - virtual void MovePopupToFront( vgui2::VPANEL panel ); - virtual void MovePopupToBack( vgui2::VPANEL panel ); - virtual void SolveTraverse( vgui2::VPANEL panel, bool forceApplySchemeSettings ); - virtual void PaintTraverse( vgui2::VPANEL panel ); - virtual void EnableMouseCapture( vgui2::VPANEL panel, bool state ); - virtual void GetWorkspaceBounds( int &x, int &y, int &wide, int &tall ); - virtual void GetAbsoluteWindowBounds( int &x, int &y, int &wide, int &tall ); - virtual void GetProportionalBase( int &width, int &height ); - virtual void CalculateMouseVisible(); - virtual bool NeedKBInput(); - virtual bool HasCursorPosFunctions(); - virtual void SurfaceGetCursorPos( int &x, int &y ); - virtual void SurfaceSetCursorPos( int x, int y ); - virtual void DrawTexturedPolygon( vgui2::VGuiVertex *pVertices, int n ); - virtual int GetFontAscent( vgui2::HFont font, wchar_t wch ); - virtual void SetAllowHTMLJavaScript( bool state ); - virtual void SetLanguage( const char *pchLang ); - virtual const char *GetLanguage(); - virtual bool DeleteTextureByID( int id ); - virtual void DrawUpdateRegionTextureBGRA( int nTextureID, int x, int y, const unsigned char *pchData, int wide, int tall ); - virtual void DrawSetTextureBGRA( int id, const unsigned char *bgra, int wide, int tall ); - virtual void CreateBrowser( vgui2::VPANEL panel, IHTMLResponses *pBrowser, bool bPopupWindow, const char *pchUserAgentIdentifier ); - virtual void RemoveBrowser( vgui2::VPANEL panel, IHTMLResponses *pBrowser ); - virtual IHTMLChromeController *AccessChromeHTMLController(); + 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 ); From 5ecc53ac4334bcb26746a08f4457f69f01d86e85 Mon Sep 17 00:00:00 2001 From: Bien Pham Date: Sun, 6 Nov 2022 01:44:44 +0800 Subject: [PATCH 05/14] vgui2: do not unload filesystem_stdio engine will do it --- vgui2_int.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/vgui2_int.cpp b/vgui2_int.cpp index 508ba41..b00729d 100644 --- a/vgui2_int.cpp +++ b/vgui2_int.cpp @@ -288,7 +288,6 @@ void VGUI2_Shutdown( void ) return; baseUI.Shutdown(); - UnloadModule( fileSystemModule ); fileSystemModule = nullptr; fileSystem = nullptr; } From a9e2ce76f878581b23570ddebc07808fc38f8c28 Mon Sep 17 00:00:00 2001 From: Bien Pham Date: Tue, 8 Nov 2022 08:29:38 +0800 Subject: [PATCH 06/14] vgui2: correctly initialize root panel size --- vgui2-dev | 2 +- vgui2_int.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/vgui2-dev b/vgui2-dev index 5fd52f3..bb7fdba 160000 --- a/vgui2-dev +++ b/vgui2-dev @@ -1 +1 @@ -Subproject commit 5fd52f39ec87117ed10a538da949ba61e52ffd9a +Subproject commit bb7fdba43994bf27934d75d5031d917a448e1010 diff --git a/vgui2_int.cpp b/vgui2_int.cpp index b00729d..f7b8c84 100644 --- a/vgui2_int.cpp +++ b/vgui2_int.cpp @@ -58,7 +58,7 @@ class BaseUI : public IBaseUI public: BaseUI() : initialized( 0 ), numFactories( 0 ) { } void Initialize( CreateInterfaceFn *factories, int count ) override; - void Start( IEngineSurface *engineSurface, int interfaceVersion ) 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; @@ -126,14 +126,14 @@ void BaseUI::Initialize( CreateInterfaceFn *factories, int count ) initialized = 1; } -void BaseUI::Start( IEngineSurface *engineSurface, int interfaceVersion ) +void BaseUI::Start( int width, int height ) { if ( !initialized ) return; rootPanel = new RootPanel( nullptr, "RootPanel" ); rootPanel->SetCursor( vgui2::dc_none ); - rootPanel->SetBounds( 0, 0, 40, 30 ); + rootPanel->SetBounds( 0, 0, width, height ); rootPanel->SetPaintBorderEnabled( false ); rootPanel->SetPaintBackgroundEnabled( false ); rootPanel->SetPaintEnabled( false ); @@ -276,7 +276,7 @@ void VGUI2_Startup( const char *clientlib, int width, int height ) factories[2] = GetFactory( LoadModule( clientlib ) ); baseUI.Initialize( factories, 3 ); - baseUI.Start( nullptr, 0 ); + baseUI.Start( width, height ); } rootPanel->SetBounds( 0, 0, width, height ); From 99930948d3ff992ad43c6a8613006b3b50dc3990 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Tue, 2 May 2023 01:54:41 +0300 Subject: [PATCH 07/14] Rename vguiapi_t to legacy_vguiapi_t --- vgui_int.cpp | 4 ++-- vgui_main.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/vgui_int.cpp b/vgui_int.cpp index 1506767..4659af7 100644 --- a/vgui_int.cpp +++ b/vgui_int.cpp @@ -27,7 +27,7 @@ from your version. #include "xash3d_types.h" namespace vgui_support { -vguiapi_t *g_api; +legacy_vguiapi_t *g_api; Panel *rootpanel = NULL; CEngineSurface *surface = NULL; @@ -109,7 +109,7 @@ void *VGui_GetPanel( void ) #define InitAPI InitVGUISupportAPI #endif -extern "C" EXPORT void InitAPI(vguiapi_t * api) +extern "C" EXPORT void InitAPI( legacy_vguiapi_t *api ) { g_api = api; g_api->Startup = VGui_Startup; diff --git a/vgui_main.h b/vgui_main.h index 5819531..05a0989 100644 --- a/vgui_main.h +++ b/vgui_main.h @@ -47,7 +47,7 @@ from your version. namespace vgui_support { -extern vguiapi_t *g_api; +extern legacy_vguiapi_t *g_api; using namespace vgui; From 99e802165c4809d95bc10656255479e41d41070d Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Tue, 2 May 2023 02:05:27 +0300 Subject: [PATCH 08/14] gitmodules: switch to our vgui2-dev fork --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 1fc267e..5863fcf 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,4 +3,4 @@ url = https://github.com/FWGS/vgui-dev [submodule "vgui2-dev"] path = vgui2-dev - url = https://github.com/kungfulon/vgui2-dev.git + url = https://github.com/FWGS/vgui2-dev.git From abdeb1ff9226b2de36a661aa3e3511811740650f Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Tue, 2 May 2023 02:31:39 +0300 Subject: [PATCH 09/14] vgui2_surf: fix for deprecated Q_strcpy, also do not null terminate Q_strncpy, it always null terminates --- vgui2_surf.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/vgui2_surf.cpp b/vgui2_surf.cpp index 4fc1ece..d08c7c0 100644 --- a/vgui2_surf.cpp +++ b/vgui2_surf.cpp @@ -643,14 +643,13 @@ void VGUI2Surface::SetAllowHTMLJavaScript( bool state ) void VGUI2Surface::SetLanguage( const char *pchLang ) { - if ( pchLang != nullptr ) + if( pchLang != nullptr ) { - Q_strncpy( language, pchLang, sizeof( language ) ); - language[sizeof( language ) - 1] = '\0'; + Q_strncpy( language, pchLang, sizeof( language )); } else { - Q_strcpy( language, "english" ); + Q_strncpy( language, "english", sizeof( language )); } } From 5848b3167cf4907ec87ca8f067141646e4be4b33 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Tue, 2 May 2023 02:32:12 +0300 Subject: [PATCH 10/14] Port to new interface --- vgui2_gameui.cpp | 4 +-- vgui2_int.cpp | 29 +++++++++++----------- vgui2_surf.cpp | 4 +-- vgui_int.cpp | 64 ++++++++++++++++++++++++++---------------------- vgui_main.h | 2 +- 5 files changed, 55 insertions(+), 48 deletions(-) diff --git a/vgui2_gameui.cpp b/vgui2_gameui.cpp index 6d7e79c..b686cfc 100644 --- a/vgui2_gameui.cpp +++ b/vgui2_gameui.cpp @@ -28,8 +28,8 @@ from your version. namespace vgui_support { -extern vguiapi_t *g_api; -}; +extern vgui_support_api_t *g_api; +} bool GameUIFuncs::IsKeyDown( const char *keyname, bool &isdown ) { diff --git a/vgui2_int.cpp b/vgui2_int.cpp index f7b8c84..f4eae8d 100644 --- a/vgui2_int.cpp +++ b/vgui2_int.cpp @@ -35,8 +35,8 @@ from your version. namespace vgui_support { -extern vguiapi_t *g_api; -}; +extern vgui_support_api_t *g_api; +} // namespace vgui_support class RootPanel : public vgui2::Panel { @@ -89,17 +89,17 @@ static GameUIFuncs gameUIFuncs; static inline void *LoadModule( const char *module ) { - return vgui_support::g_api->COM_LoadLibrary( module, false, false ); + return vgui_support::g_api->LoadLibrary( module, false, false ); } static inline CreateInterfaceFn GetFactory( void *module ) { - return (CreateInterfaceFn)vgui_support::g_api->COM_GetProcAddress( module, "CreateInterface" ); + return (CreateInterfaceFn)vgui_support::g_api->GetProcAddress( module, "CreateInterface" ); } static inline void UnloadModule( void *module ) { - vgui_support::g_api->COM_FreeLibrary( module ); + vgui_support::g_api->FreeLibrary( module ); } void BaseUI::Initialize( CreateInterfaceFn *factories, int count ) @@ -154,8 +154,8 @@ void BaseUI::Start( int width, int height ) 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 @@ -262,29 +262,30 @@ extern "C" EXPORT IBaseInterface *CreateInterface( const char *pName, int *pRetu return nullptr; } -void VGUI2_Startup( const char *clientlib, int width, int height ) +void VGUI2_Startup( void *clientInstance, int width, int height ) { - if ( rootPanel == nullptr ) + if( rootPanel == nullptr && clientInstance != nullptr ) { fileSystemModule = LoadModule( "filesystem_stdio." OS_LIB_EXT ); auto fileSystemFactory = GetFactory( fileSystemModule ); - fileSystem = (IVFileSystem009 *)fileSystemFactory( "VFileSystem009", nullptr ); + fileSystem = (IVFileSystem009 *)fileSystemFactory( FILESYSTEM_INTERFACE_VERSION, nullptr ); CreateInterfaceFn factories[3]; factories[0] = CreateInterface; factories[1] = fileSystemFactory; - factories[2] = GetFactory( LoadModule( clientlib ) ); + factories[2] = GetFactory( clientInstance ); baseUI.Initialize( factories, 3 ); baseUI.Start( width, height ); } - rootPanel->SetBounds( 0, 0, width, height ); + if( rootPanel != nullptr ) + rootPanel->SetBounds( 0, 0, width, height ); } void VGUI2_Shutdown( void ) { - if ( rootPanel == nullptr ) + if( rootPanel == nullptr ) return; baseUI.Shutdown(); @@ -294,13 +295,13 @@ void VGUI2_Shutdown( void ) void VGUI2_ScreenSize( int &width, int &height ) { - if ( rootPanel ) + if( rootPanel ) rootPanel->GetSize( width, height ); } bool VGUI2_UseVGUI1( void ) { - if ( clientVGUI ) + if( clientVGUI ) return clientVGUI->UseVGUI1(); return true; } diff --git a/vgui2_surf.cpp b/vgui2_surf.cpp index d08c7c0..3128301 100644 --- a/vgui2_surf.cpp +++ b/vgui2_surf.cpp @@ -30,8 +30,8 @@ from your version. namespace vgui_support { -extern vguiapi_t *g_api; -}; +extern vgui_support_api_t *g_api; +} void VGUI2_ScreenSize( int &width, int &height ); diff --git a/vgui_int.cpp b/vgui_int.cpp index c60eb2d..1623ef1 100644 --- a/vgui_int.cpp +++ b/vgui_int.cpp @@ -26,26 +26,29 @@ from your version. #include "vgui_main.h" #include "xash3d_types.h" -void VGUI2_Startup( const char *clientlib, int width, int height ); +void VGUI2_Startup( void *clientlib, int width, int height ); void VGUI2_Shutdown( void ); bool VGUI2_UseVGUI1( void ); void VGUI2_Paint( void ); namespace vgui_support { -legacy_vguiapi_t *g_api; +vgui_support_api_t *g_api; Panel *rootpanel = NULL; CEngineSurface *surface = NULL; CEngineApp staticApp; -void VGui_Startup( const char *clientlib, int width, int height ) +void VGui_ClientStartup( void *clientInstance, int width, int height ) +{ + VGUI2_Startup( clientInstance, width, height ); +} + +void VGui_Startup( 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 ); + VGUI2_Startup( NULL, width, height ); rootpanel->setSize( width, height ); return; } @@ -79,35 +82,31 @@ void VGui_Shutdown( void ) rootpanel = NULL; surface = NULL; - - VGUI2_Shutdown(); } void VGui_Paint( void ) { int w, h; - //if( cls.state != ca_active || !rootpanel ) - // return; if( !g_api->IsInGame() || !rootpanel ) return; // setup the base panel to cover the screen Panel *pVPanel = surface->getEmbeddedPanel(); - if( !pVPanel ) return; - //SDL_GetWindowSize(host.hWnd, &w, &h); - //host.input_enabled = rootpanel->isVisible(); + if( !pVPanel ) + return; + rootpanel->getSize(w, h); EnableScissor( true ); - if ( VGUI2_UseVGUI1() ) + if( VGUI2_UseVGUI1( )) { staticApp.externalTick (); pVPanel->setBounds( 0, 0, w, h ); pVPanel->repaint(); - // paint everything + // paint everything pVPanel->paintTraverse(); } else @@ -123,19 +122,26 @@ void *VGui_GetPanel( void ) } } -#ifdef INTERNAL_VGUI_SUPPORT -#define InitAPI InitVGUISupportAPI -#endif - -extern "C" EXPORT void InitAPI( legacy_vguiapi_t *api ) +static vgui_support_interface_t vguifuncs = +{ + VGui_Startup, + VGui_Shutdown, + VGui_GetPanel, + VGui_Paint, + VGUI_Mouse, + VGUI_Key, + VGUI_MouseMove, + VGUI_TextInput, + VGui_ClientStartup +}; + +extern "C" int EXPORT GetVGUISupportAPI( int version, vgui_support_interface_t *iface, vgui_support_api_t *engfuncs ) { - g_api = api; - g_api->Startup = VGui_Startup; - g_api->Shutdown = VGui_Shutdown; - g_api->GetPanel = VGui_GetPanel; - g_api->Paint = VGui_Paint; - g_api->Mouse = VGUI_Mouse; - g_api->MouseMove = VGUI_MouseMove; - g_api->Key = VGUI_Key; - g_api->TextInput = VGUI_TextInput; + if( version != VGUI_SUPPORT_API_VERSION ) + return 0; + + g_api = engfuncs; // TODO: do not store the pointer + memcpy( iface, &vguifuncs, sizeof( vguifuncs )); + + return VGUI_SUPPORT_API_VERSION; } diff --git a/vgui_main.h b/vgui_main.h index 05a0989..ad401d6 100644 --- a/vgui_main.h +++ b/vgui_main.h @@ -47,7 +47,7 @@ from your version. namespace vgui_support { -extern legacy_vguiapi_t *g_api; +extern vgui_support_api_t *g_api; using namespace vgui; From 27fbcbf2bf09ce93a5f49f891878a00cf0cb6eb6 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Tue, 2 May 2023 08:47:14 +0300 Subject: [PATCH 11/14] vgui2_int: make VGUI2 optional, detect by loaded libraries. Warnings fixes --- vgui2_int.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/vgui2_int.cpp b/vgui2_int.cpp index f4eae8d..4f5b9fc 100644 --- a/vgui2_int.cpp +++ b/vgui2_int.cpp @@ -46,8 +46,8 @@ class RootPanel : public vgui2::Panel vgui2::VPANEL IsWithinTraverse( int x, int y, bool traversePopups ) override { auto panel = vgui2::Panel::IsWithinTraverse( x, y, traversePopups ); - if ( panel == GetVPanel() ) - return NULL; + if( panel == GetVPanel() ) + return 0; return panel; } @@ -104,12 +104,16 @@ static inline void UnloadModule( void *module ) void BaseUI::Initialize( CreateInterfaceFn *factories, int count ) { - if ( initialized ) + if( initialized ) return; vgui2Module = LoadModule( "vgui2." OS_LIB_EXT ); chromeModule = LoadModule( "chromehtml." OS_LIB_EXT ); + // a1ba: make VGUI2 optional + if( !vgui2Module || !chromeModule ) + return; + factoryList[numFactories++] = factories[0]; factoryList[numFactories++] = GetFactory( vgui2Module ); factoryList[numFactories++] = factories[1]; @@ -214,11 +218,11 @@ void BaseUI::CallEngineSurfaceAppHandler( void *event, void *userData ) void BaseUI::Paint( int x, int y, int right, int bottom ) { - if ( !initialized ) + if( !initialized ) return; vgui2::VPANEL panel = vgui2::surface()->GetEmbeddedPanel(); - if ( panel == NULL ) + if( !panel ) return; vgui2::ivgui()->RunFrame(); From 0780206daad7c61c4053571453bbd6be1b8fc49d Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Wed, 3 May 2023 04:33:08 +0300 Subject: [PATCH 12/14] Refactoring to share more code and definitions between VGUI1 and VGUI2. * Reformat files too. --- vgui2-dev | 2 +- vgui2_gameui.cpp | 8 +- vgui2_int.cpp | 82 +++++++++--------- vgui2_surf.cpp | 221 +++++++++++++++++++++++++++-------------------- vgui2_surf.h | 3 + vgui_input.cpp | 66 +++++++------- vgui_int.cpp | 70 ++++++++------- vgui_main.h | 194 +++++++++++++++++++++++++---------------- vgui_surf.cpp | 211 +++++++++++++++++++++++++++++++++++++------- 9 files changed, 543 insertions(+), 314 deletions(-) diff --git a/vgui2-dev b/vgui2-dev index bb7fdba..6fde440 160000 --- a/vgui2-dev +++ b/vgui2-dev @@ -1 +1 @@ -Subproject commit bb7fdba43994bf27934d75d5031d917a448e1010 +Subproject commit 6fde44035c31c0ed098bdbd907bda6627846651d diff --git a/vgui2_gameui.cpp b/vgui2_gameui.cpp index b686cfc..7e0eac9 100644 --- a/vgui2_gameui.cpp +++ b/vgui2_gameui.cpp @@ -23,13 +23,8 @@ from your version. */ +#include "vgui_main.h" #include "vgui2_gameui.h" -#include - -namespace vgui_support -{ -extern vgui_support_api_t *g_api; -} bool GameUIFuncs::IsKeyDown( const char *keyname, bool &isdown ) { @@ -50,7 +45,6 @@ const char *GameUIFuncs::Key_BindingForKey( int keynum ) 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 ) diff --git a/vgui2_int.cpp b/vgui2_int.cpp index 4f5b9fc..f074ac4 100644 --- a/vgui2_int.cpp +++ b/vgui2_int.cpp @@ -23,21 +23,17 @@ from your version. */ -#include -#include -#include "vgui2_surf.h" -#include "vgui2_gameui.h" +#include #include #include #include -#include -#include +#include +#include "vgui_main.h" +#include "vgui2_surf.h" +#include "vgui2_gameui.h" namespace vgui_support { -extern vgui_support_api_t *g_api; -} // namespace vgui_support - class RootPanel : public vgui2::Panel { public: @@ -89,17 +85,17 @@ static GameUIFuncs gameUIFuncs; static inline void *LoadModule( const char *module ) { - return vgui_support::g_api->LoadLibrary( module, false, false ); + return g_api->LoadLibrary( module, false, false ); } static inline CreateInterfaceFn GetFactory( void *module ) { - return (CreateInterfaceFn)vgui_support::g_api->GetProcAddress( module, "CreateInterface" ); + return (CreateInterfaceFn)g_api->GetProcAddress( module, "CreateInterface" ); } static inline void UnloadModule( void *module ) { - vgui_support::g_api->FreeLibrary( module ); + g_api->FreeLibrary( module ); } void BaseUI::Initialize( CreateInterfaceFn *factories, int count ) @@ -119,7 +115,7 @@ void BaseUI::Initialize( CreateInterfaceFn *factories, int count ) factoryList[numFactories++] = factories[1]; factoryList[numFactories++] = GetFactory( chromeModule ); - if ( factories[2] != nullptr ) + if( factories[2] != nullptr ) { factoryList[numFactories++] = factories[2]; clientVGUI = (IClientVGUI *)factoryList[4]( VCLIENTVGUI_INTERFACE_VERSION, nullptr ); @@ -132,7 +128,7 @@ void BaseUI::Initialize( CreateInterfaceFn *factories, int count ) void BaseUI::Start( int width, int height ) { - if ( !initialized ) + if( !initialized ) return; rootPanel = new RootPanel( nullptr, "RootPanel" ); @@ -167,12 +163,12 @@ void BaseUI::Start( int width, int height ) vgui2::ivgui()->Start(); vgui2::ivgui()->SetSleep( false ); - if ( clientVGUI ) + if( clientVGUI ) clientVGUI->Initialize( factoryList, numFactories ); rootPanel->SetScheme( "ClientScheme" ); - if ( clientVGUI ) + if( clientVGUI ) { clientVGUI->Start(); clientVGUI->SetParent( rootPanel->GetVPanel() ); @@ -183,13 +179,13 @@ void BaseUI::Start( int width, int height ) void BaseUI::Shutdown() { - if ( !initialized ) + if( !initialized ) return; vgui2::ivgui()->RunFrame(); vgui2::ivgui()->Shutdown(); - if ( clientVGUI ) + if( clientVGUI ) { clientVGUI->Shutdown(); clientVGUI = nullptr; @@ -206,7 +202,7 @@ void BaseUI::Shutdown() int BaseUI::Key_Event( int down, int keynum, const char *pszCurrentBinding ) { - if ( !initialized ) + if( !initialized ) return 0; return vgui2::surface()->NeedKBInput(); @@ -249,20 +245,23 @@ void BaseUI::ShowConsole() { } -extern "C" EXPORT IBaseInterface *CreateInterface( const char *pName, int *pReturnCode ) +extern "C" EXPORT void *CreateInterface( const char *pName, int *pReturnCode ) { - if ( pReturnCode ) *pReturnCode = IFACE_OK; + if( pReturnCode ) + *pReturnCode = IFACE_OK; + + if( !Q_strcmp( pName, BASEUI_INTERFACE_VERSION ) ) + return &baseUI; - if ( !Q_strcmp( pName, BASEUI_INTERFACE_VERSION ) ) - return (IBaseUI *)&baseUI; + if( !Q_strcmp( pName, VGUI_SURFACE_INTERFACE_VERSION ) ) + return &vgui2Surface; - if ( !Q_strcmp( pName, VGUI_SURFACE_INTERFACE_VERSION ) ) - return (vgui2::ISurface *)&vgui2Surface; + if( !Q_strcmp( pName, VENGINE_GAMEUIFUNCS_VERSION ) ) + return &gameUIFuncs; - if ( !Q_strcmp( pName, VENGINE_GAMEUIFUNCS_VERSION ) ) - return (IGameUIFuncs *)&gameUIFuncs; + if( pReturnCode ) + *pReturnCode = IFACE_FAILED; - if ( pReturnCode ) *pReturnCode = IFACE_FAILED; return nullptr; } @@ -274,12 +273,14 @@ void VGUI2_Startup( void *clientInstance, int width, int height ) auto fileSystemFactory = GetFactory( fileSystemModule ); fileSystem = (IVFileSystem009 *)fileSystemFactory( FILESYSTEM_INTERFACE_VERSION, nullptr ); - CreateInterfaceFn factories[3]; - factories[0] = CreateInterface; - factories[1] = fileSystemFactory; - factories[2] = GetFactory( clientInstance ); + CreateInterfaceFn factories[] = + { + CreateInterface, + fileSystemFactory, + GetFactory( clientInstance ) + }; - baseUI.Initialize( factories, 3 ); + baseUI.Initialize( factories, sizeof( factories ) / sizeof( factories[0] )); baseUI.Start( width, height ); } @@ -312,7 +313,7 @@ bool VGUI2_UseVGUI1( void ) void VGUI2_Paint( void ) { - if ( rootPanel == nullptr ) + if( rootPanel == nullptr ) return; int wide, tall; @@ -322,10 +323,10 @@ void VGUI2_Paint( void ) void VGUI2_Key( VGUI_KeyAction action, VGUI_KeyCode code ) { - if ( rootPanel == nullptr ) + if( rootPanel == nullptr ) return; - if ( !baseUI.Key_Event( action == KA_PRESSED, code + 1, "" ) ) + if( !baseUI.Key_Event( action == KA_PRESSED, code + 1, "" ) ) return; switch ( action ) @@ -344,10 +345,10 @@ void VGUI2_Key( VGUI_KeyAction action, VGUI_KeyCode code ) void VGUI2_Mouse( VGUI_MouseAction action, int code ) { - if ( rootPanel == nullptr ) + if( rootPanel == nullptr ) return; - if ( !vgui2::surface()->IsCursorVisible() ) + if( !vgui2::surface()->IsCursorVisible() ) return; switch ( action ) @@ -369,7 +370,7 @@ void VGUI2_Mouse( VGUI_MouseAction action, int code ) void VGUI2_MouseMove( int x, int y ) { - if ( rootPanel == nullptr ) + if( rootPanel == nullptr ) return; vgui2::inputinternal()->InternalCursorMoved( x, y ); @@ -377,6 +378,7 @@ void VGUI2_MouseMove( int x, int y ) void VGUI2_TextInput( const char *text ) { - for ( const char *c = text; *c; c++ ) + for( const char *c = text; *c; c++ ) vgui2::inputinternal()->InternalKeyTyped( *c ); } +} // namespace vgui_support diff --git a/vgui2_surf.cpp b/vgui2_surf.cpp index 3128301..5245a8d 100644 --- a/vgui2_surf.cpp +++ b/vgui2_surf.cpp @@ -23,30 +23,26 @@ from your version. */ -#include "vgui2_surf.h" +#include #include -#include #include +#include "vgui_main.h" +#include "vgui2_surf.h" -namespace vgui_support -{ -extern vgui_support_api_t *g_api; -} - -void VGUI2_ScreenSize( int &width, int &height ); +using namespace vgui_support; static const auto VPANEL_NORMAL = ( (vgui2::SurfacePlat *)NULL ); static const auto VPANEL_MINIMIZED = ( (vgui2::SurfacePlat *)0x00000001 ); void VGUI2Surface::Shutdown() { - if ( chromeController ) + if( chromeController ) chromeController->Shutdown(); } void VGUI2Surface::RunFrame() { - if ( chromeController ) + if( chromeController ) chromeController->RunFrame(); } @@ -67,7 +63,7 @@ void VGUI2Surface::PushMakeCurrent( vgui2::VPANEL panel, bool useInsets ) int clipRect[4]; int wide, tall; - if ( useInsets ) + if( useInsets ) vgui2::ipanel()->GetInset( panel, insets[0], insets[1], insets[2], insets[3] ); vgui2::ipanel()->GetAbsPos( panel, absExtents[0], absExtents[1] ); @@ -77,86 +73,105 @@ void VGUI2Surface::PushMakeCurrent( vgui2::VPANEL panel, bool useInsets ) vgui2::ipanel()->GetClipRect( panel, clipRect[0], clipRect[1], clipRect[2], clipRect[3] ); - // engineSurface->PushMakeCurrent( insets, absExtents, clipRect ); + VGUIPanel p( panel ); + surface->PushMakeCurrent( p, insets, absExtents, clipRect ); } void VGUI2Surface::PopMakeCurrent( vgui2::VPANEL panel ) { - // engineSurface->PopMakeCurrent(); + VGUIPanel p( panel ); + surface->PopMakeCurrent( p ); } void VGUI2Surface::DrawSetColor( int r, int g, int b, int a ) { - // engineSurface->DrawSetColor( r, g, b, a ); + surface->drawSetColor( r, g, b, a ); } void VGUI2Surface::DrawSetColor( Color col ) { - // engineSurface->DrawSetColor( col[0], col[1], col[2], col[3] ); + surface->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 ); + surface->drawFilledRect( x0, y0, x1, y1 ); } void VGUI2Surface::DrawOutlinedRect( int x0, int y0, int x1, int y1 ) { - // engineSurface->DrawOutlinedRect( x0, y0, x1, y1 ); + surface->drawOutlinedRect( x0, y0, x1, y1 ); } void VGUI2Surface::DrawLine( int x0, int y0, int x1, int y1 ) { - // engineSurface sucks + surface->drawLine( x0, y0, x1, y1 ); } void VGUI2Surface::DrawPolyLine( int *px, int *py, int numPoints ) { - // engineSurface sucks + surface->drawPolyLine( px, py, numPoints ); } void VGUI2Surface::DrawSetTextFont( vgui2::HFont font ) { - // engineSurface->DrawSetTextFont( font ); + if( font == -1 ) + return; + + surface->drawSetTextFont((vgui::Font *)font ); } void VGUI2Surface::DrawSetTextColor( int r, int g, int b, int a ) { - // engineSurface->DrawSetTextColor( r, g, b, a ); + surface->drawSetTextColor( r, g, b, a ); } void VGUI2Surface::DrawSetTextColor( Color col ) { - // engineSurface->DrawSetTextColor( col[0], col[1], col[2], col[3] ); + surface->drawSetTextColor( col[0], col[1], col[2], col[3] ); } void VGUI2Surface::DrawSetTextPos( int x, int y ) { - // engineSurface->DrawSetTextPos( x, y ); + surface->drawSetTextPos( x, y ); } void VGUI2Surface::DrawGetTextPos( int &x, int &y ) { - // engineSurface->DrawGetTextPos( x, y ); + surface->drawGetTextPos( x, y ); } void VGUI2Surface::DrawPrintText( const wchar_t *text, int textLen ) { + if( !text || textLen <= 0 ) + return; + + auto str = new char[textLen + 1]; + + wcstombs( str, text, textLen ); + surface->drawPrintText( str, textLen ); + + delete[] str; // engineSurface->DrawPrintText( text, textLen ); } void VGUI2Surface::DrawUnicodeChar( wchar_t wch ) { - // engineSurface->DrawUnicodeChar( wch, false ); + char s[16]; // MB_CUR_MAX makes it VLA + auto len = wctomb( s, wch ); + + surface->drawPrintText( s, len ); } void VGUI2Surface::DrawUnicodeCharAdd( wchar_t wch ) { - // engineSurface->DrawUnicodeChar( wch, true ); + // TODO: any difference? + DrawUnicodeChar( wch ); } void VGUI2Surface::DrawFlushText() { + // TODO: stub } vgui2::IHTML *VGUI2Surface::CreateHTMLWindow( vgui2::IHTMLEvents *events, vgui2::VPANEL context ) @@ -174,39 +189,38 @@ void VGUI2Surface::DeleteHTMLWindow( vgui2::IHTML *htmlwin ) void VGUI2Surface::DrawSetTextureFile( int id, const char *filename, int hardwareFilter, bool forceReload ) { - // engineSurface->DrawSetTextureFile( id, filename ); + surface->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 ); + surface->drawSetTextureRGBA( id, (const char *)rgba, wide, tall ); } void VGUI2Surface::DrawSetTexture( int id ) { - // engineSurface->DrawSetTexture( id ); + surface->drawSetTexture( id ); } void VGUI2Surface::DrawGetTextureSize( int id, int &wide, int &tall ) { - wide = 1; - tall = 1; - // engineSurface->DrawGetTextureSize( id, wide, tall ); + surface->drawGetTextureSize( id, wide, tall ); } void VGUI2Surface::DrawTexturedRect( int x0, int y0, int x1, int y1 ) { - // engineSurface->DrawTexturedRect( x0, y0, x1, y1 ); + surface->drawTexturedRect( x0, y0, x1, y1 ); } bool VGUI2Surface::IsTextureIDValid( int id ) { + // TODO: do anything here? return true; } int VGUI2Surface::CreateNewTextureID( bool procedural ) { - return vgui_support::g_api->GenerateTexture(); + return surface->createNewTextureID(); } void VGUI2Surface::GetScreenSize( int &wide, int &tall ) @@ -222,7 +236,7 @@ void VGUI2Surface::BringToFront( vgui2::VPANEL panel ) { vgui2::ipanel()->MoveToFront( panel ); - if ( vgui2::ipanel()->IsPopup( panel ) ) + if( vgui2::ipanel()->IsPopup( panel ) ) MovePopupToFront( panel ); } @@ -237,7 +251,7 @@ void VGUI2Surface::SetPanelVisible( vgui2::VPANEL panel, bool state ) void VGUI2Surface::SetMinimized( vgui2::VPANEL panel, bool state ) { - if ( !state ) + if( !state ) { vgui2::ipanel()->SetPlat( panel, VPANEL_NORMAL ); return; @@ -266,14 +280,14 @@ 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 ) + 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 ) ) + if( !popups.hasElement( panel ) ) popups.addElement( panel ); } @@ -288,18 +302,18 @@ 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 ) + if( cursor >= vgui2::dc_last || cursor == vgui2::dc_waitarrow || cursor == vgui2::dc_blank ) return; - if ( currentCursor != cursor ) + if( currentCursor != cursor ) { currentCursor = cursor; // Hack to make it compatible with VGUI1 - if ( cursor > vgui2::dc_waitarrow ) + if( cursor > vgui2::dc_waitarrow ) --cursor; - vgui_support::g_api->CursorSelect( (VGUI_DefaultCursor)cursor ); + g_api->CursorSelect( (VGUI_DefaultCursor)cursor ); } } @@ -359,7 +373,7 @@ void VGUI2Surface::SetTranslateExtendedKeys( bool state ) vgui2::VPANEL VGUI2Surface::GetTopmostPopup() { - if ( popups.getCount() > 0 ) + if( popups.getCount() > 0 ) return popups[popups.getCount() - 1]; return NULL; @@ -369,7 +383,7 @@ void VGUI2Surface::SetTopLevelFocus( vgui2::VPANEL panel ) { while ( panel ) { - if ( vgui2::ipanel()->IsPopup( panel ) && vgui2::ipanel()->IsMouseInputEnabled( panel ) ) + if( vgui2::ipanel()->IsPopup( panel ) && vgui2::ipanel()->IsMouseInputEnabled( panel ) ) { BringToFront( panel ); break; @@ -381,45 +395,53 @@ void VGUI2Surface::SetTopLevelFocus( vgui2::VPANEL panel ) vgui2::HFont VGUI2Surface::CreateFont() { - return -1; - // return engineSurface->CreateFont(); + return surface->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 ); + return surface->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 ); + return surface->addCustomFontFile( fontFileName ); } int VGUI2Surface::GetFontTall( vgui2::HFont font ) { - return 1; - // return engineSurface->GetFontTall( font ); + return surface->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 ); + surface->getCharABCWide( font,ch, a, b, c ); } int VGUI2Surface::GetCharacterWidth( vgui2::HFont font, int ch ) { - return 1; - // return engineSurface->GetCharacterWidth( font, ch ); + int a, b, c; + GetCharABCwide( font, ch, a, b, c ); + return a + b + c; } void VGUI2Surface::GetTextSize( vgui2::HFont font, const wchar_t *text, int &wide, int &tall ) { - wide = 1; - tall = 1; - // engineSurface->GetTextSize( font, text, wide, tall ); + if( !text ) + { + wide = 1; + tall = 1; + return; + } + + auto len = wcslen( text ); + auto str = new char[len + 1]; + + wcstombs( str, text, len ); + surface->getTextSize( font, str, wide, tall ); + + delete[] str; } vgui2::VPANEL VGUI2Surface::GetNotifyPanel() @@ -433,7 +455,7 @@ void VGUI2Surface::SetNotifyIcon( vgui2::VPANEL context, vgui2::HTexture icon, v void VGUI2Surface::PlaySound( const char *fileName ) { - // vgui_support::g_api->PlaySound( fileName ); + surface->playSound( fileName ); } int VGUI2Surface::GetPopupCount() @@ -443,7 +465,7 @@ int VGUI2Surface::GetPopupCount() vgui2::VPANEL VGUI2Surface::GetPopup( int index ) { - if ( 0 <= index && index < popups.getCount() ) + if( 0 <= index && index < popups.getCount() ) return popups[index]; return NULL; @@ -451,13 +473,13 @@ vgui2::VPANEL VGUI2Surface::GetPopup( int index ) bool VGUI2Surface::ShouldPaintChildPanel( vgui2::VPANEL panel ) { - if ( restrictedPanel != NULL && vgui2::ipanel()->HasParent( panel, restrictedPanel ) ) + if( restrictedPanel != NULL && vgui2::ipanel()->HasParent( panel, restrictedPanel ) ) return false; - if ( !vgui2::ipanel()->IsPopup( panel ) ) + if( !vgui2::ipanel()->IsPopup( panel ) ) return true; - if ( popups.hasElement( panel ) ) + if( popups.hasElement( panel ) ) vgui2::ipanel()->Render_SetPopupVisible( panel, true ); return false; @@ -470,7 +492,7 @@ bool VGUI2Surface::RecreateContext( vgui2::VPANEL panel ) void VGUI2Surface::AddPanel( vgui2::VPANEL panel ) { - if ( !vgui2::ipanel()->IsPopup( panel ) ) + if( !vgui2::ipanel()->IsPopup( panel ) ) return; CreatePopup( panel, false, false, false, true, true ); @@ -480,13 +502,13 @@ void VGUI2Surface::ReleasePanel( vgui2::VPANEL panel ) { popups.removeElement( panel ); - if ( restrictedPanel == panel ) + if( restrictedPanel == panel ) restrictedPanel = NULL; } void VGUI2Surface::MovePopupToFront( vgui2::VPANEL panel ) { - if ( popups.hasElement( panel ) ) + if( popups.hasElement( panel ) ) { popups.removeElement( panel ); popups.addElement( panel ); @@ -495,7 +517,7 @@ void VGUI2Surface::MovePopupToFront( vgui2::VPANEL panel ) void VGUI2Surface::MovePopupToBack( vgui2::VPANEL panel ) { - if ( popups.hasElement( panel ) ) + if( popups.hasElement( panel ) ) { popups.removeElement( panel ); popups.insertElementAt( panel, 0 ); @@ -511,26 +533,26 @@ void VGUI2Surface::SolveTraverse( vgui2::VPANEL panel, bool forceApplySchemeSett void VGUI2Surface::PaintTraverse( vgui2::VPANEL panel ) { - if ( !vgui2::ipanel()->IsVisible( panel ) ) + if( !vgui2::ipanel()->IsVisible( panel ) ) return; - if ( panel != GetEmbeddedPanel() ) + if( panel != GetEmbeddedPanel() ) { vgui2::ipanel()->PaintTraverse( panel, true, true ); return; } - if ( restrictedPanel ) + if( restrictedPanel ) panel = restrictedPanel; - for ( int i = 0; i < popups.getCount(); ++i ) + 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 ) + for( int i = 0; i < popups.getCount(); ++i ) { - if ( vgui2::ipanel()->Render_GetPopupVisible( popups[i] ) ) + if( vgui2::ipanel()->Render_GetPopupVisible( popups[i] ) ) vgui2::ipanel()->PaintTraverse( popups[i], true, true ); } } @@ -562,20 +584,20 @@ void VGUI2Surface::GetProportionalBase( int &width, int &height ) void VGUI2Surface::CalculateMouseVisible() { - if ( ignoreMouseVisCalc ) + if( ignoreMouseVisCalc ) return; needMouse = false; needKB = false; - for ( int i = 0; i < popups.getCount(); ++i ) + 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 ) ) + if( !vgui2::ipanel()->IsVisible( parent ) ) { visible = false; break; @@ -584,7 +606,7 @@ void VGUI2Surface::CalculateMouseVisible() parent = vgui2::ipanel()->GetParent( parent ); } - if ( !visible ) + if( !visible ) continue; // TODO: Uncomment these once fully implemented to enable input capture @@ -594,7 +616,7 @@ void VGUI2Surface::CalculateMouseVisible() UnlockCursor(); - if ( needMouse ) + if( needMouse ) { SetCursor( vgui2::dc_arrow ); } @@ -617,23 +639,22 @@ bool VGUI2Surface::HasCursorPosFunctions() void VGUI2Surface::SurfaceGetCursorPos( int &x, int &y ) { - vgui_support::g_api->GetCursorPos( &x, &y ); + g_api->GetCursorPos( &x, &y ); } void VGUI2Surface::SurfaceSetCursorPos( int x, int y ) { - // vgui_support::g_api->SetCursorPos( x, y ); + // g_api->SetCursorPos( x, y ); } void VGUI2Surface::DrawTexturedPolygon( vgui2::VGuiVertex *pVertices, int n ) { - // engineSurface->DrawTexturedPolygon( pVertices, n ); + surface->drawTexturedPolygon( pVertices, n ); } int VGUI2Surface::GetFontAscent( vgui2::HFont font, wchar_t wch ) { - // return some arbitrary number for now - return 0; + return surface->getFontAscent( font, wch ); } void VGUI2Surface::SetAllowHTMLJavaScript( bool state ) @@ -660,29 +681,37 @@ const char *VGUI2Surface::GetLanguage() bool VGUI2Surface::DeleteTextureByID( int id ) { - return false; - // return engineSurface->DeleteTextureByID( id ); + return surface->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 ); + surface->drawSubTextureBGRA( 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 ); + auto p = new unsigned char[wide * tall * 4]; + for( int i = 0; i < wide * tall * 4; i += 4 ) + { + p[i + 0] = bgra[i + 2]; + p[i + 1] = bgra[i + 1]; + p[i + 2] = bgra[i + 0]; + p[i + 3] = bgra[i + 3]; + } + surface->drawSetTextureRGBA( id, (const char *)p, wide, tall ); + delete[] p; } void VGUI2Surface::CreateBrowser( vgui2::VPANEL panel, IHTMLResponses *pBrowser, bool bPopupWindow, const char *pchUserAgentIdentifier ) { - if ( chromeController ) + if( chromeController ) chromeController->CreateBrowser( pBrowser, false, "Valve Half-Life" ); } void VGUI2Surface::RemoveBrowser( vgui2::VPANEL panel, IHTMLResponses *pBrowser ) { - if ( chromeController ) + if( chromeController ) chromeController->RemoveBrowser( pBrowser ); } @@ -712,7 +741,7 @@ void VGUI2Surface::Init( vgui2::VPANEL _embeddedPanel, IHTMLChromeController *pC SetEmbeddedPanel( _embeddedPanel ); chromeController = pChromeController; - if ( chromeController ) + if( chromeController ) { chromeController->Init( "htmlcache", "htmlcookies" ); chromeController->SetCefThreadTargetFrameRate( 60 ); @@ -734,10 +763,10 @@ void VGUI2Surface::SetIgnoreMouseVisCalc( bool state ) void VGUI2Surface::InternalSchemeSettingsTraverse( vgui2::VPANEL panel, bool forceApplySchemeSettings ) { - for ( int i = 0; i < vgui2::ipanel()->GetChildCount( panel ); ++i ) + for( int i = 0; i < vgui2::ipanel()->GetChildCount( panel ); ++i ) { vgui2::VPANEL child = vgui2::ipanel()->GetChild( panel, i ); - if ( forceApplySchemeSettings || vgui2::ipanel()->IsVisible( child ) ) + if( forceApplySchemeSettings || vgui2::ipanel()->IsVisible( child ) ) InternalSchemeSettingsTraverse( child, forceApplySchemeSettings ); } @@ -748,10 +777,10 @@ void VGUI2Surface::InternalThinkTraverse( vgui2::VPANEL panel ) { vgui2::ipanel()->Think( panel ); - for ( int i = 0; i < vgui2::ipanel()->GetChildCount( panel ); ++i ) + for( int i = 0; i < vgui2::ipanel()->GetChildCount( panel ); ++i ) { vgui2::VPANEL child = vgui2::ipanel()->GetChild( panel, i ); - if ( vgui2::ipanel()->IsVisible( child ) ) + if( vgui2::ipanel()->IsVisible( child ) ) InternalThinkTraverse( child ); } } @@ -760,10 +789,10 @@ void VGUI2Surface::InternalSolveTraverse( vgui2::VPANEL panel ) { vgui2::ipanel()->Solve( panel ); - for ( int i = 0; i < vgui2::ipanel()->GetChildCount( panel ); ++i ) + for( int i = 0; i < vgui2::ipanel()->GetChildCount( panel ); ++i ) { vgui2::VPANEL child = vgui2::ipanel()->GetChild( panel, i ); - if ( vgui2::ipanel()->IsVisible( child ) ) + if( vgui2::ipanel()->IsVisible( child ) ) InternalSolveTraverse( child ); } } diff --git a/vgui2_surf.h b/vgui2_surf.h index 387170d..571f122 100644 --- a/vgui2_surf.h +++ b/vgui2_surf.h @@ -31,6 +31,8 @@ from your version. #include #include +namespace vgui_support +{ class VGUI2Surface : public vgui2::ISurface { public: @@ -156,5 +158,6 @@ class VGUI2Surface : public vgui2::ISurface bool ignoreMouseVisCalc; vgui2::HCursor currentCursor; }; +} // vgui_support #endif // VGUI2_SURFACE_H diff --git a/vgui_input.cpp b/vgui_input.cpp index 232a2dc..f5138de 100644 --- a/vgui_input.cpp +++ b/vgui_input.cpp @@ -24,93 +24,85 @@ from your version. */ #define OEMRESOURCE // for OCR_* cursor junk - #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) +namespace vgui_support +{ +void VGUI_Key( VGUI_KeyAction action, VGUI_KeyCode code ) { - if ( !VGUI2_UseVGUI1() ) + if( !VGUI2_UseVGUI1( )) { VGUI2_Key( action, code ); return; } - App *pApp = App::getInstance(); - if(!surface) + if( !surface ) return; + + vgui::App *pApp = vgui::App::getInstance(); + switch( action ) { case KA_PRESSED: - pApp->internalKeyPressed( (KeyCode) code, surface ); + pApp->internalKeyPressed((vgui::KeyCode)code, surface ); break; case KA_RELEASED: - pApp->internalKeyReleased( (KeyCode) code, surface ); + pApp->internalKeyReleased((vgui::KeyCode)code, surface ); break; case KA_TYPED: - pApp->internalKeyTyped( (KeyCode) code, surface ); + pApp->internalKeyTyped((vgui::KeyCode)code, surface ); break; } - //fprintf(stdout,"vgui_support: VGUI key action %d %d\n", action, code); - //fflush(stdout); } -void VGUI_Mouse(VGUI_MouseAction action, int code) +void VGUI_Mouse( VGUI_MouseAction action, int code ) { - if ( !VGUI2_UseVGUI1() ) + if( !VGUI2_UseVGUI1( )) { VGUI2_Mouse( action, code ); return; } - App *pApp = App::getInstance(); - if(!surface) + if( !surface ) return; + + vgui::App *pApp = vgui::App::getInstance(); + switch( action ) { case MA_PRESSED: - pApp->internalMousePressed( (MouseCode) code, surface ); + pApp->internalMousePressed((vgui::MouseCode)code, surface ); break; case MA_RELEASED: - pApp->internalMouseReleased( (MouseCode) code, surface ); + pApp->internalMouseReleased((vgui::MouseCode)code, surface ); break; case MA_DOUBLE: - pApp->internalMouseDoublePressed( (MouseCode) code, surface ); + pApp->internalMouseDoublePressed((vgui::MouseCode)code, surface ); break; case MA_WHEEL: - //fprintf(stdout, "vgui_support: VGUI mouse wheeled %d %d\n", action, code); pApp->internalMouseWheeled( code, surface ); break; } - //fprintf(stdout, "vgui_support: VGUI mouse action %d %d\n", action, code); - //fflush(stdout); } -void VGUI_MouseMove(int x, int y) +void VGUI_MouseMove( int x, int y ) { - if ( !VGUI2_UseVGUI1() ) + 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); - if(!surface) + if( !surface ) return; - pApp->internalCursorMoved( x, y, surface ); + + vgui::App::getInstance()->internalCursorMoved( x, y, surface ); } -void VGUI_TextInput(const char *text) +void VGUI_TextInput( const char *text ) { - if ( !VGUI2_UseVGUI1() ) + if( !VGUI2_UseVGUI1( )) VGUI2_TextInput( text ); } -} + +} // namespace vgui_support diff --git a/vgui_int.cpp b/vgui_int.cpp index 1623ef1..f3343e7 100644 --- a/vgui_int.cpp +++ b/vgui_int.cpp @@ -26,25 +26,33 @@ from your version. #include "vgui_main.h" #include "xash3d_types.h" -void VGUI2_Startup( void *clientlib, int width, int height ); -void VGUI2_Shutdown( void ); -bool VGUI2_UseVGUI1( void ); -void VGUI2_Paint( void ); - -namespace vgui_support { +using namespace vgui; +namespace vgui_support +{ vgui_support_api_t *g_api; +CEngineSurface *surface = nullptr; + +static Panel *rootpanel = nullptr; +static class CEngineApp : public App +{ +public: + explicit CEngineApp( bool externalMain = true ); + void main( int argc, char *argv[] ) override; +} staticApp; -Panel *rootpanel = NULL; -CEngineSurface *surface = NULL; -CEngineApp staticApp; +CEngineApp::CEngineApp( bool externalMain ) : + App( externalMain ) +{ + +} -void VGui_ClientStartup( void *clientInstance, int width, int height ) +void CEngineApp::main( int argc, char *argv[] ) { - VGUI2_Startup( clientInstance, width, height ); + } -void VGui_Startup( int width, int height ) +static void VGUI_Startup( int width, int height ) { if( rootpanel ) { @@ -64,16 +72,13 @@ void VGui_Startup( int width, int height ) staticApp.setMinimumTickMillisInterval( 0 ); surface = new CEngineSurface( rootpanel ); - rootpanel->setSurfaceBaseTraverse( surface ); - - //ASSERT( rootpanel->getApp() != NULL ); - //ASSERT( rootpanel->getSurfaceBase() != NULL ); + rootpanel->setSurfaceBaseTraverse( surface ); - g_api->DrawInit (); + g_api->DrawInit(); } -void VGui_Shutdown( void ) +static void VGUI_Shutdown() { staticApp.stop(); @@ -84,7 +89,7 @@ void VGui_Shutdown( void ) surface = NULL; } -void VGui_Paint( void ) +static void VGUI_Paint() { int w, h; @@ -116,32 +121,39 @@ void VGui_Paint( void ) EnableScissor( false ); } -void *VGui_GetPanel( void ) + +static void *VGUI_GetPanel() { return (void *)rootpanel; } -} static vgui_support_interface_t vguifuncs = { - VGui_Startup, - VGui_Shutdown, - VGui_GetPanel, - VGui_Paint, + VGUI_Startup, + VGUI_Shutdown, + VGUI_GetPanel, + VGUI_Paint, VGUI_Mouse, VGUI_Key, VGUI_MouseMove, VGUI_TextInput, - VGui_ClientStartup + VGUI2_Startup }; -extern "C" int EXPORT GetVGUISupportAPI( int version, vgui_support_interface_t *iface, vgui_support_api_t *engfuncs ) +extern "C" int EXPORT GetVGUISupportAPI( int version, + vgui_support_interface_t *iface, vgui_support_api_t *engfuncs ) { + static vgui_support_api_t api; + if( version != VGUI_SUPPORT_API_VERSION ) return 0; - g_api = engfuncs; // TODO: do not store the pointer - memcpy( iface, &vguifuncs, sizeof( vguifuncs )); + memcpy( &api, engfuncs, sizeof( api )); + g_api = &api; + + memcpy( iface, &vguifuncs, sizeof( *iface )); return VGUI_SUPPORT_API_VERSION; } + +} // namespace vgui_support diff --git a/vgui_main.h b/vgui_main.h index ad401d6..93acbfc 100644 --- a/vgui_main.h +++ b/vgui_main.h @@ -30,30 +30,54 @@ from your version. #else #include #endif - #include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "vgui_api.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include namespace vgui_support { extern vgui_support_api_t *g_api; -using namespace vgui; +struct VGUIPanel +{ + VGUIPanel( vgui::Panel *pPanel ) + { + this->pPanel = pPanel; + this->vgui2 = false; + } + VGUIPanel( vgui2::VPANEL vPanel ) + { + this->vPanel = vPanel; + this->vgui2 = true; + } + VGUIPanel() + { + pPanel = nullptr; + vgui2 = false; + } + + union + { + vgui::Panel *pPanel; + vgui2::VPANEL vPanel; + }; + bool vgui2; +}; struct PaintStack { - Panel *m_pPanel; + VGUIPanel panel; int iTranslateX; int iTranslateY; int iScissorLeft; @@ -62,9 +86,68 @@ struct PaintStack int iScissorBottom; }; -class CEngineSurface : public SurfaceBase +class CEngineSurface : public vgui::SurfaceBase { +public: + CEngineSurface( vgui::Panel *embeddedPanel ); + ~CEngineSurface(); + + virtual bool setFullscreenMode( int wide, int tall, int bpp ) override; + virtual void setWindowedMode() override; + virtual void setTitle( const char *title ) override; + virtual void createPopup( vgui::Panel *embeddedPanel ) override; + virtual bool isWithin( int x, int y ) override; + virtual bool hasFocus() override; + virtual void GetMousePos( int &x, int &y ) override; + + vgui::Panel *getEmbeddedPanel(); + void drawPrintChar( int x, int y, int wide, int tall, float s0, float t0, float s1, float t1, int color[] ); + +protected: + virtual int createNewTextureID() override; + virtual void drawSetColor( int r, int g, int b, int a ) override; + virtual void drawSetTextColor( int r, int g, int b, int a ) override; + virtual void drawFilledRect( int x0, int y0, int x1, int y1 ) override; + virtual void drawOutlinedRect( int x0, int y0, int x1, int y1 ) override; + virtual void drawSetTextFont( vgui::Font *font ) override; + virtual void drawSetTextPos( int x, int y ) override; + virtual void drawPrintText( const char *text, int textLen ) override; + virtual void drawSetTextureRGBA( int id, const char *rgba, int wide, int tall ) override; + virtual void drawSetTexture( int id ) override; + virtual void drawTexturedRect( int x0, int y0, int x1, int y1 ) override; + virtual void setCursor( vgui::Cursor *cursor ) override; + virtual void pushMakeCurrent( vgui::Panel *panel, bool useInsets ) override; + virtual void popMakeCurrent( vgui::Panel *panel ) override; + virtual void enableMouseCapture( bool state ); + virtual void invalidate( vgui::Panel *panel ); + virtual void setAsTopMost( bool state ); + virtual void applyChanges(); + virtual void swapBuffers(); + private: + void SetupPaintState( const PaintStack *paintState ); + void InitVertex( vpoint_t &vertex, int x, int y, float u, float v ); + + // VGUI2 Surface funcs + void PushMakeCurrent( VGUIPanel panel, int insets[4], int absExtents[4], int clipRect[4] ); + void PopMakeCurrent( VGUIPanel panel ); + void drawLine( int x0, int y0, int x1, int y1 ); + void drawPolyLine( int *px, int *py, int numPoints ); + void drawGetTextPos( int &x, int &y ); + void drawSetTextureFile( int id, const char *filename ); + void drawGetTextureSize( int id, int &wide, int &tall ); + vgui2::HFont createFont(); + bool addGlyphSetToFont( vgui2::HFont font, const char *fontName, int tall, int weight, bool italic, bool underline, bool strikeout, bool symbol ); + bool addCustomFontFile( const char *fontFileName ); + int getFontTall( vgui2::HFont font ); + void getCharABCWide( vgui2::HFont font, int ch, int &a, int &b, int &c ); + int getCharWidth( vgui2::HFont font, int ch ); + void getTextSize( vgui2::HFont font, const char *text, int &wide, int &tall ); + void playSound( const char *filename ); + void drawTexturedPolygon( vgui2::VGuiVertex *verts, int n ); + int getFontAscent( vgui2::HFont font, int ch ); + bool deleteTextureByID( int id ); + void drawSubTextureBGRA( int id, int x, int y, const byte *bgra, int wide, int tall ); // point translation for current panel int _translateX; @@ -72,75 +155,25 @@ class CEngineSurface : public SurfaceBase // the size of the window to draw into int _surfaceExtents[4]; - - void SetupPaintState( const PaintStack *paintState ); - void InitVertex( vpoint_t &vertex, int x, int y, float u, float v ); -public: - CEngineSurface( Panel *embeddedPanel ); - ~CEngineSurface(); -public: - virtual Panel *getEmbeddedPanel( void ); - virtual bool setFullscreenMode( int wide, int tall, int bpp ); - virtual void setWindowedMode( void ); - virtual void setTitle( const char *title ) { } - virtual void createPopup( Panel* embeddedPanel ) { } - virtual bool isWithin( int x, int y ) { return true; } - virtual bool hasFocus( void ); - // now it's not abstract class, yay - virtual void GetMousePos(int &x, int &y) { - g_api->GetCursorPos(&x, &y); - } - void drawPrintChar(int x, int y, int wide, int tall, float s0, float t0, float s1, float t1, int color[]); protected: - virtual int createNewTextureID( void ); - virtual void drawSetColor( int r, int g, int b, int a ); - virtual void drawSetTextColor( int r, int g, int b, int a ); - virtual void drawFilledRect( int x0, int y0, int x1, int y1 ); - virtual void drawOutlinedRect( int x0,int y0,int x1,int y1 ); - virtual void drawSetTextFont( Font *font ); - virtual void drawSetTextPos( int x, int y ); - virtual void drawPrintText( const char* text, int textLen ); - virtual void drawSetTextureRGBA( int id, const char* rgba, int wide, int tall ); - virtual void drawSetTexture( int id ); - virtual void drawTexturedRect( int x0, int y0, int x1, int y1 ); - virtual bool createPlat( void ) { return false; } - virtual bool recreateContext( void ) { return false; } - virtual void setCursor( Cursor* cursor ); - virtual void pushMakeCurrent( Panel* panel, bool useInsets ); - virtual void popMakeCurrent( Panel* panel ); - - // not used in engine instance - virtual void enableMouseCapture( bool state ) { } - virtual void invalidate( Panel *panel ) { } - virtual void setAsTopMost( bool state ) { } - virtual void applyChanges( void ) { } - virtual void swapBuffers( void ) { } -protected: - Cursor* _hCurrentCursor; + vgui::Cursor *_hCurrentCursor; int _drawTextPos[2]; int _drawColor[4]; int _drawTextColor[4]; friend class App; friend class Panel; + friend class VGUI2Surface; }; -// initialize VGUI::App as external (part of engine) -class CEngineApp : public App -{ -public: - CEngineApp( bool externalMain = true ) : App( externalMain ) { } - virtual void main( int argc, char* argv[] ) { } // stub -}; +extern CEngineSurface *surface; // // vgui_input.cpp // -void *VGui_GetPanel( void ); -void VGui_Paint( void ); -void VGUI_Mouse(VGUI_MouseAction action, int code); -void VGUI_Key(VGUI_KeyAction action, VGUI_KeyCode code); -void VGUI_MouseMove(int x, int y); -void VGUI_TextInput(const char *text); +void VGUI_Mouse( VGUI_MouseAction action, int code ); +void VGUI_Key( VGUI_KeyAction action, VGUI_KeyCode code ); +void VGUI_MouseMove( int x, int y ); +void VGUI_TextInput( const char *text ); // // vgui_clip.cpp @@ -149,8 +182,19 @@ void EnableScissor( qboolean enable ); void SetScissorRect( int left, int top, int right, int bottom ); qboolean ClipRect( const vpoint_t &inUL, const vpoint_t &inLR, vpoint_t *pOutUL, vpoint_t *pOutLR ); -extern CEngineSurface *surface; -extern Panel *root; +// +// vgui2_int.cpp +// +void VGUI2_Startup( void *clientlib, int width, int height ); +void VGUI2_Shutdown(); +bool VGUI2_UseVGUI1(); +void VGUI2_Paint(); +void VGUI2_ScreenSize( int &width, int &height ); +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 ); + } -using namespace vgui_support; -#endif//VGUI_MAIN_H + +#endif // VGUI_MAIN_H diff --git a/vgui_surf.cpp b/vgui_surf.cpp index 21802da..1da3075 100644 --- a/vgui_surf.cpp +++ b/vgui_surf.cpp @@ -30,6 +30,9 @@ from your version. #define FONT_SIZE 512 #define FONT_PAGES 8 +using namespace vgui_support; +using namespace vgui; + struct FontInfo { int id; @@ -50,7 +53,8 @@ static int staticPaintStackPos = 0; #define ColorIndex( c )((( c ) - '0' ) & 7 ) -CEngineSurface :: CEngineSurface( Panel *embeddedPanel ):SurfaceBase( embeddedPanel ) +CEngineSurface::CEngineSurface( Panel *embeddedPanel ) : + SurfaceBase( embeddedPanel ) { _embeddedPanel = embeddedPanel; _drawColor[0] = _drawColor[1] = _drawColor[2] = _drawColor[3] = 255; @@ -72,24 +76,22 @@ CEngineSurface :: CEngineSurface( Panel *embeddedPanel ):SurfaceBase( embeddedPa _translateX = _translateY = 0; } -CEngineSurface :: ~CEngineSurface( void ) +CEngineSurface::~CEngineSurface( void ) { g_api->DrawShutdown (); } -Panel *CEngineSurface :: getEmbeddedPanel( void ) +Panel *CEngineSurface::getEmbeddedPanel( void ) { return _embeddedPanel; } -bool CEngineSurface :: hasFocus( void ) +bool CEngineSurface::hasFocus( void ) { - // What differs when window does not has focus? - //return host.state != HOST_NOFOCUS; return true; } -void CEngineSurface :: setCursor( Cursor *cursor ) +void CEngineSurface::setCursor( Cursor *cursor ) { _currentCursor = cursor; @@ -99,7 +101,7 @@ void CEngineSurface :: setCursor( Cursor *cursor ) } } -void CEngineSurface :: SetupPaintState( const PaintStack *paintState ) +void CEngineSurface::SetupPaintState( const PaintStack *paintState ) { _translateX = paintState->iTranslateX; _translateY = paintState->iTranslateY; @@ -107,7 +109,7 @@ void CEngineSurface :: SetupPaintState( const PaintStack *paintState ) paintState->iScissorRight, paintState->iScissorBottom ); } -void CEngineSurface :: InitVertex( vpoint_t &vertex, int x, int y, float u, float v ) +void CEngineSurface::InitVertex( vpoint_t &vertex, int x, int y, float u, float v ) { vertex.point[0] = x + _translateX; vertex.point[1] = y + _translateY; @@ -115,12 +117,12 @@ void CEngineSurface :: InitVertex( vpoint_t &vertex, int x, int y, float u, floa vertex.coord[1] = v; } -int CEngineSurface :: createNewTextureID( void ) +int CEngineSurface::createNewTextureID( void ) { return g_api->GenerateTexture(); } -void CEngineSurface :: drawSetColor( int r, int g, int b, int a ) +void CEngineSurface::drawSetColor( int r, int g, int b, int a ) { _drawColor[0] = r; _drawColor[1] = g; @@ -128,7 +130,7 @@ void CEngineSurface :: drawSetColor( int r, int g, int b, int a ) _drawColor[3] = a; } -void CEngineSurface :: drawSetTextColor( int r, int g, int b, int a ) +void CEngineSurface::drawSetTextColor( int r, int g, int b, int a ) { _drawTextColor[0] = r; _drawTextColor[1] = g; @@ -136,7 +138,7 @@ void CEngineSurface :: drawSetTextColor( int r, int g, int b, int a ) _drawTextColor[3] = a; } -void CEngineSurface :: drawFilledRect( int x0, int y0, int x1, int y1 ) +void CEngineSurface::drawFilledRect( int x0, int y0, int x1, int y1 ) { vpoint_t rect[2]; vpoint_t clippedRect[2]; @@ -156,7 +158,7 @@ void CEngineSurface :: drawFilledRect( int x0, int y0, int x1, int y1 ) g_api->EnableTexture( true ); } -void CEngineSurface :: drawOutlinedRect( int x0, int y0, int x1, int y1 ) +void CEngineSurface::drawOutlinedRect( int x0, int y0, int x1, int y1 ) { if( _drawColor[3] >= 255 ) return; @@ -166,7 +168,7 @@ void CEngineSurface :: drawOutlinedRect( int x0, int y0, int x1, int y1 ) drawFilledRect( x1 - 1, y0 + 1, x1, y1 - 1 ); // right } -void CEngineSurface :: drawSetTextFont( Font *font ) +void CEngineSurface::drawSetTextFont( Font *font ) { staticFont = font; @@ -257,13 +259,13 @@ void CEngineSurface :: drawSetTextFont( Font *font ) } } -void CEngineSurface :: drawSetTextPos( int x, int y ) +void CEngineSurface::drawSetTextPos( int x, int y ) { _drawTextPos[0] = x; _drawTextPos[1] = y; } -void CEngineSurface :: drawPrintChar( int x, int y, int wide, int tall, float s0, float t0, float s1, float t1, int color[4] ) +void CEngineSurface::drawPrintChar( int x, int y, int wide, int tall, float s0, float t0, float s1, float t1, int color[4] ) { vpoint_t ul, lr; @@ -287,7 +289,7 @@ void CEngineSurface :: drawPrintChar( int x, int y, int wide, int tall, float s0 g_api->DrawQuad( &clippedRect[0], &clippedRect[1] ); // draw the letter } -void CEngineSurface :: drawPrintText( const char* text, int textLen ) +void CEngineSurface::drawPrintText( const char* text, int textLen ) { //return; static bool hasColor = 0; @@ -359,17 +361,17 @@ void CEngineSurface :: drawPrintText( const char* text, int textLen ) _drawTextPos[0] += iTotalWidth; } -void CEngineSurface :: drawSetTextureRGBA( int id, const char* rgba, int wide, int tall ) +void CEngineSurface::drawSetTextureRGBA( int id, const char* rgba, int wide, int tall ) { g_api->UploadTexture( id, rgba, wide, tall ); } -void CEngineSurface :: drawSetTexture( int id ) +void CEngineSurface::drawSetTexture( int id ) { g_api->BindTexture( id ); } -void CEngineSurface :: drawTexturedRect( int x0, int y0, int x1, int y1 ) +void CEngineSurface::drawTexturedRect( int x0, int y0, int x1, int y1 ) { vpoint_t rect[2]; vpoint_t clippedRect[2]; @@ -385,7 +387,7 @@ void CEngineSurface :: drawTexturedRect( int x0, int y0, int x1, int y1 ) g_api->DrawQuad( &clippedRect[0], &clippedRect[1] ); } -void CEngineSurface :: pushMakeCurrent( Panel* panel, bool useInsets ) +void CEngineSurface::pushMakeCurrent( Panel* panel, bool useInsets ) { int insets[4] = { 0, 0, 0, 0 }; int absExtents[4]; @@ -396,11 +398,83 @@ void CEngineSurface :: pushMakeCurrent( Panel* panel, bool useInsets ) panel->getAbsExtents( absExtents[0], absExtents[1], absExtents[2], absExtents[3] ); panel->getClipRect( clipRect[0], clipRect[1], clipRect[2], clipRect[3] ); + VGUIPanel p( panel ); + PushMakeCurrent( p, insets, absExtents, clipRect ); +} + +void CEngineSurface::popMakeCurrent( Panel *panel ) +{ + VGUIPanel p( panel ); + PopMakeCurrent( p ); +} + +void CEngineSurface::GetMousePos( int &x, int &y ) +{ + g_api->GetCursorPos( &x, &y ); +} + +bool CEngineSurface::setFullscreenMode( int wide, int tall, int bpp ) +{ + // stub + return false; +} + +void CEngineSurface::setWindowedMode( void ) +{ + // stub +} + +void CEngineSurface::setTitle( const char *title ) +{ + // stub +} + +void CEngineSurface::createPopup( vgui::Panel *embeddedPanel ) +{ + // stub +} + +bool CEngineSurface::isWithin( int x, int y ) +{ + // stub + return true; +} + +void CEngineSurface::enableMouseCapture( bool state ) +{ + // stub +} + +void CEngineSurface::invalidate( vgui::Panel *panel ) +{ + // stub +} + +void CEngineSurface::setAsTopMost( bool state ) +{ + // stub +} + +void CEngineSurface::applyChanges() +{ + // stub +} + +void CEngineSurface::swapBuffers() +{ + // stub +} + +// +// VGUI2 extended surface +// +void CEngineSurface::PushMakeCurrent( VGUIPanel panel, int insets[4], int absExtents[4], int clipRect[4] ) +{ PaintStack *paintState = &paintStack[staticPaintStackPos]; assert( staticPaintStackPos < MAX_PAINT_STACK ); - paintState->m_pPanel = panel; + paintState->panel = panel; // determine corrected top left origin paintState->iTranslateX = insets[0] + absExtents[0]; @@ -412,29 +486,108 @@ void CEngineSurface :: pushMakeCurrent( Panel* panel, bool useInsets ) paintState->iScissorBottom = clipRect[3]; SetupPaintState( paintState ); + staticPaintStackPos++; } - -void CEngineSurface :: popMakeCurrent( Panel *panel ) + +void CEngineSurface::PopMakeCurrent( VGUIPanel p ) { int top = staticPaintStackPos - 1; // more pops that pushes? assert( top >= 0 ); + // a1ba: replace asserts by proper checks!!! // didn't pop in reverse order of push? - assert( paintStack[top].m_pPanel == panel ); + assert( paintStack[top].panel.vgui2 == p.vgui2 ); + if( p.vgui2 ) + assert( paintStack[top].panel.vPanel == p.vPanel ); + else + assert( paintStack[top].panel.pPanel == p.pPanel ); staticPaintStackPos--; if( top > 0 ) SetupPaintState( &paintStack[top-1] ); } -bool CEngineSurface :: setFullscreenMode( int wide, int tall, int bpp ) +void CEngineSurface::drawLine( int x0, int y0, int x1, int y1 ) +{ + +} + +void CEngineSurface::drawPolyLine( int *px, int *py, int numPoints ) +{ + +} + +void CEngineSurface::drawGetTextPos( int &x, int &y ) +{ + +} + +void CEngineSurface::drawSetTextureFile( int id, const char *filename ) +{ + +} + +void CEngineSurface::drawGetTextureSize( int id, int &wide, int &tall ) +{ + +} + +vgui2::HFont CEngineSurface::createFont() +{ + return -1; +} + +bool CEngineSurface::addGlyphSetToFont( vgui2::HFont font, const char *fontName, int tall, int weight, bool italic, bool underline, bool strikeout, bool symbol ) { return false; } - -void CEngineSurface :: setWindowedMode( void ) + +bool CEngineSurface::addCustomFontFile( const char *fontFileName ) { + return false; +} + +int CEngineSurface::getFontTall( vgui2::HFont font ) +{ + return 0; } + +void CEngineSurface::getCharABCWide( vgui2::HFont font, int ch, int &a, int &b, int &c ) +{ + a = b = c = 1; +} + +void CEngineSurface::getTextSize( vgui2::HFont font, const char *text, int &wide, int &tall ) +{ + wide = tall = 1; +} + +void CEngineSurface::playSound( const char *filename ) +{ + +} + +void CEngineSurface::drawTexturedPolygon( vgui2::VGuiVertex *verts, int n ) +{ + +} + +int CEngineSurface::getFontAscent( vgui2::HFont font, int ch ) +{ + return 0; +} + +bool CEngineSurface::deleteTextureByID( int id ) +{ + return false; +} + +void CEngineSurface::drawSubTextureBGRA( int id, int x, int y, const byte *bgra, int wide, int tall ) +{ + +} + + From 631a9df02a5075b8500a262749efc0f98421d9d4 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Wed, 3 May 2023 20:06:15 +0300 Subject: [PATCH 13/14] vgui2_int: fix fetching current mod on Linux, as VGUI2's GetCommandLine doesn't work here --- vgui2_int.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/vgui2_int.cpp b/vgui2_int.cpp index f074ac4..703738a 100644 --- a/vgui2_int.cpp +++ b/vgui2_int.cpp @@ -23,14 +23,15 @@ from your version. */ +#include #include #include #include #include -#include #include "vgui_main.h" #include "vgui2_surf.h" #include "vgui2_gameui.h" +#include "filesystem.h" namespace vgui_support { @@ -77,7 +78,7 @@ class BaseUI : public IBaseUI static RootPanel *rootPanel; static IClientVGUI *clientVGUI; static void *fileSystemModule; -static IVFileSystem009 *fileSystem; +static fs_api_t *fs; static VGUI2Surface vgui2Surface; static BaseUI baseUI; @@ -152,7 +153,9 @@ void BaseUI::Start( int width, int height ) vgui2::localize()->AddFile( vgui2::filesystem(), "resource/valve_%language%.txt" ); char szMod[32]; - vgui2::system()->GetCommandLineParamValue( "-game", szMod, sizeof( szMod ) ); + // doesn't work on Linux + // vgui2::system()->GetCommandLineParamValue( "-game", szMod, sizeof( szMod ) ); + Q_strncpy( szMod, fs->GetFileSystemGlobals()->GameInfo->gamefolder, sizeof( szMod )); char szLocalizeFile[260]; Q_snprintf( szLocalizeFile, sizeof( szLocalizeFile ), "resource/%s_%%language%%.txt", szMod ); @@ -271,7 +274,7 @@ void VGUI2_Startup( void *clientInstance, int width, int height ) { fileSystemModule = LoadModule( "filesystem_stdio." OS_LIB_EXT ); auto fileSystemFactory = GetFactory( fileSystemModule ); - fileSystem = (IVFileSystem009 *)fileSystemFactory( FILESYSTEM_INTERFACE_VERSION, nullptr ); + fs = (fs_api_t *)fileSystemFactory( FS_API_CREATEINTERFACE_TAG, NULL ); CreateInterfaceFn factories[] = { @@ -288,14 +291,14 @@ void VGUI2_Startup( void *clientInstance, int width, int height ) rootPanel->SetBounds( 0, 0, width, height ); } -void VGUI2_Shutdown( void ) +void VGUI2_Shutdown() { if( rootPanel == nullptr ) return; baseUI.Shutdown(); fileSystemModule = nullptr; - fileSystem = nullptr; + fs = nullptr; } void VGUI2_ScreenSize( int &width, int &height ) From aba6eddea14b5aaa2d54211094cfe836e8fb0b37 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Wed, 3 May 2023 20:07:20 +0300 Subject: [PATCH 14/14] vgui2_surf: implement simple drawing --- vgui2_surf.cpp | 32 +++++++++++++++++---------- vgui_main.h | 3 ++- vgui_surf.cpp | 59 +++++++++++++++++++++++++++++++++++--------------- 3 files changed, 64 insertions(+), 30 deletions(-) diff --git a/vgui2_surf.cpp b/vgui2_surf.cpp index 5245a8d..20417f9 100644 --- a/vgui2_surf.cpp +++ b/vgui2_surf.cpp @@ -85,12 +85,14 @@ void VGUI2Surface::PopMakeCurrent( vgui2::VPANEL panel ) void VGUI2Surface::DrawSetColor( int r, int g, int b, int a ) { - surface->drawSetColor( r, g, b, a ); + // VGUI2 inverts alpha + + surface->drawSetColor( r, g, b, 255 - a ); } void VGUI2Surface::DrawSetColor( Color col ) { - surface->drawSetColor( col[0], col[1], col[2], col[3] ); + DrawSetColor( col[0], col[1], col[2], col[3] ); } void VGUI2Surface::DrawFilledRect( int x0, int y0, int x1, int y1 ) @@ -115,20 +117,17 @@ void VGUI2Surface::DrawPolyLine( int *px, int *py, int numPoints ) void VGUI2Surface::DrawSetTextFont( vgui2::HFont font ) { - if( font == -1 ) - return; - - surface->drawSetTextFont((vgui::Font *)font ); + surface->drawSetTextFont( font ); } void VGUI2Surface::DrawSetTextColor( int r, int g, int b, int a ) { - surface->drawSetTextColor( r, g, b, a ); + surface->drawSetTextColor( r, g, b, 255 - a ); } void VGUI2Surface::DrawSetTextColor( Color col ) { - surface->drawSetTextColor( col[0], col[1], col[2], col[3] ); + DrawSetTextColor( col[0], col[1], col[2], col[3] ); } void VGUI2Surface::DrawSetTextPos( int x, int y ) @@ -610,8 +609,8 @@ void VGUI2Surface::CalculateMouseVisible() 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] ); + needMouse = needMouse || vgui2::ipanel()->IsMouseInputEnabled( popups[i] ); + needKB = needKB || vgui2::ipanel()->IsKeyBoardInputEnabled( popups[i] ); } UnlockCursor(); @@ -684,9 +683,18 @@ bool VGUI2Surface::DeleteTextureByID( int id ) return surface->deleteTextureByID( id ); } -void VGUI2Surface::DrawUpdateRegionTextureBGRA( int nTextureID, int x, int y, const unsigned char *pchData, int wide, int tall ) +void VGUI2Surface::DrawUpdateRegionTextureBGRA( int id, int x, int y, const unsigned char *bgra, int wide, int tall ) { - surface->drawSubTextureBGRA( nTextureID, x, y, pchData, wide, tall ); + auto p = new unsigned char[wide * tall * 4]; + for( int i = 0; i < wide * tall * 4; i += 4 ) + { + p[i + 0] = bgra[i + 2]; + p[i + 1] = bgra[i + 1]; + p[i + 2] = bgra[i + 0]; + p[i + 3] = bgra[i + 3]; + } + surface->drawSubTextureRGBA( id, x, y, p, wide, tall ); + delete[] p; } void VGUI2Surface::DrawSetTextureBGRA( int id, const unsigned char *bgra, int wide, int tall ) diff --git a/vgui_main.h b/vgui_main.h index 93acbfc..de952db 100644 --- a/vgui_main.h +++ b/vgui_main.h @@ -139,6 +139,7 @@ class CEngineSurface : public vgui::SurfaceBase vgui2::HFont createFont(); bool addGlyphSetToFont( vgui2::HFont font, const char *fontName, int tall, int weight, bool italic, bool underline, bool strikeout, bool symbol ); bool addCustomFontFile( const char *fontFileName ); + void drawSetTextFont( vgui2::HFont font ); int getFontTall( vgui2::HFont font ); void getCharABCWide( vgui2::HFont font, int ch, int &a, int &b, int &c ); int getCharWidth( vgui2::HFont font, int ch ); @@ -147,7 +148,7 @@ class CEngineSurface : public vgui::SurfaceBase void drawTexturedPolygon( vgui2::VGuiVertex *verts, int n ); int getFontAscent( vgui2::HFont font, int ch ); bool deleteTextureByID( int id ); - void drawSubTextureBGRA( int id, int x, int y, const byte *bgra, int wide, int tall ); + void drawSubTextureRGBA( int id, int x, int y, const byte *bgra, int wide, int tall ); // point translation for current panel int _translateX; diff --git a/vgui_surf.cpp b/vgui_surf.cpp index 1da3075..f5e1fdf 100644 --- a/vgui_surf.cpp +++ b/vgui_surf.cpp @@ -24,6 +24,7 @@ from your version. */ #include +#include #include "vgui_main.h" #define MAX_PAINT_STACK 16 @@ -306,11 +307,11 @@ void CEngineSurface::drawPrintText( const char* text, int textLen ) int j, iTotalWidth = 0; int curTextColor[4]; - // HACKHACK: allow color strings in VGUI + // HACKHACK: allow color strings in VGUI if( numColor != 7 ) { for( j = 0; j < 3; j++ ) // grab predefined color - curTextColor[j] = g_api->GetColor(numColor,j); + curTextColor[j] = g_api->GetColor( numColor, j ); } else { @@ -326,7 +327,8 @@ void CEngineSurface::drawPrintText( const char* text, int textLen ) hasColor = true; return; // skip '^' } - else if( hasColor && isdigit( *text )) + + if( hasColor && isdigit( *text )) { numColor = ColorIndex( *text ); hasColor = false; // handled @@ -334,13 +336,16 @@ void CEngineSurface::drawPrintText( const char* text, int textLen ) } else hasColor = false; } + + // reset + g_api->ProcessUtfChar( 0 ); + for( int i = 0; i < textLen; i++ ) { int curCh = g_api->ProcessUtfChar( (unsigned char)text[i] ); + if( !curCh ) - { continue; - } int abcA, abcB, abcC; @@ -512,27 +517,32 @@ void CEngineSurface::PopMakeCurrent( VGUIPanel p ) void CEngineSurface::drawLine( int x0, int y0, int x1, int y1 ) { - + // TODO: implement this + // will require updating RefAPI or implement VGUI drawing + // through TriAPI? } void CEngineSurface::drawPolyLine( int *px, int *py, int numPoints ) { - + // TODO: see drawLine comment } void CEngineSurface::drawGetTextPos( int &x, int &y ) { - + x = _drawTextPos[0]; + y = _drawTextPos[1]; } void CEngineSurface::drawSetTextureFile( int id, const char *filename ) { - + g_api->BindTexture( id ); + g_api->UploadTextureFile( id, filename ); } void CEngineSurface::drawGetTextureSize( int id, int &wide, int &tall ) { - + g_api->BindTexture( id ); + g_api->GetTextureSizes( &wide, &tall ); } vgui2::HFont CEngineSurface::createFont() @@ -550,9 +560,15 @@ bool CEngineSurface::addCustomFontFile( const char *fontFileName ) return false; } +void CEngineSurface::drawSetTextFont( vgui2::HFont font ) +{ + // TODO: use mainui_cpp font renderer here +} + int CEngineSurface::getFontTall( vgui2::HFont font ) { - return 0; + // add random tall + return 32; } void CEngineSurface::getCharABCWide( vgui2::HFont font, int ch, int &a, int &b, int &c ) @@ -562,32 +578,41 @@ void CEngineSurface::getCharABCWide( vgui2::HFont font, int ch, int &a, int &b, void CEngineSurface::getTextSize( vgui2::HFont font, const char *text, int &wide, int &tall ) { - wide = tall = 1; + int lines = 0; + for( const char *p = text; *p; p = Q_strchrnul( p, '\n' )) + lines++; + + // TODO: add some height because client.dll uses this function to determine + // engine string drawing functions height (as GoldSrc uses VGUI2 internally anyway) + // this will be rewritten to real function later + tall = lines * getFontTall( font ); + wide = 1; } void CEngineSurface::playSound( const char *filename ) { - + g_api->StartSound( filename ); } void CEngineSurface::drawTexturedPolygon( vgui2::VGuiVertex *verts, int n ) { - + // TODO: see drawLine comment } int CEngineSurface::getFontAscent( vgui2::HFont font, int ch ) { - return 0; + return getFontTall( font ) * 0.8; } bool CEngineSurface::deleteTextureByID( int id ) { + // TODO: see drawLine comment return false; } -void CEngineSurface::drawSubTextureBGRA( int id, int x, int y, const byte *bgra, int wide, int tall ) +void CEngineSurface::drawSubTextureRGBA( int id, int x, int y, const byte *rgba, int wide, int tall ) { - + g_api->UploadTextureBlock( id, x, y, rgba, wide, tall ); }