Integrate FWGS vgui_support

This commit is contained in:
Alibek Omarov 2018-04-14 01:49:14 +03:00
parent 158db1c454
commit 5a1b03ac20
27 changed files with 4275 additions and 1282 deletions

View File

@ -3476,6 +3476,11 @@ float Voice_GetControlFloat( VoiceTweakControl iControl )
return 1.0f;
}
static void GAME_EXPORT VGui_ViewportPaintBackground( int extents[4] )
{
// stub
}
// shared between client and server
triangleapi_t gTriApi =
{
@ -3758,7 +3763,6 @@ void CL_UnloadProgs( void )
CL_FreeParticles();
CL_ClearAllRemaps();
Mod_ClearUserData();
VGui_Shutdown();
// NOTE: HLFX 0.5 has strange bug: hanging on exit if no map was loaded
if( Q_stricmp( GI->gamedir, "hlfx" ) || GI->version != 0.5f )
@ -3768,6 +3772,7 @@ void CL_UnloadProgs( void )
Cvar_FullSet( "host_clientloaded", "0", FCVAR_READ_ONLY );
COM_FreeLibrary( clgame.hInstance );
VGui_Shutdown();
Mem_FreePool( &cls.mempool );
Mem_FreePool( &clgame.mempool );
memset( &clgame, 0, sizeof( clgame ));
@ -3792,6 +3797,11 @@ qboolean CL_LoadProgs( const char *name )
clgame.mempool = Mem_AllocPool( "Client Edicts Zone" );
clgame.entities = NULL;
// NOTE: important stuff!
// vgui must startup BEFORE loading client.dll to avoid get error ERROR_NOACESS
// during LoadLibrary
VGui_Startup( gameui.globals->scrWidth, gameui.globals->scrHeight );
clgame.hInstance = COM_LoadLibrary( name, false, false );
if( !clgame.hInstance ) return false;
@ -3887,9 +3897,6 @@ qboolean CL_LoadProgs( const char *name )
CL_InitStudioAPI( );
// initialize VGui
VGui_Startup ();
// trying to grab them from client.dll
cl_righthand = Cvar_FindVar( "cl_righthand" );
@ -3897,4 +3904,4 @@ qboolean CL_LoadProgs( const char *name )
cl_righthand = Cvar_Get( "cl_righthand", "0", FCVAR_ARCHIVE, "flip viewmodel (left to right)" );
return true;
}
}

View File

@ -683,7 +683,7 @@ void SCR_VidInit( void )
gameui.globals->scrWidth = glState.width;
gameui.globals->scrHeight = glState.height;
VGui_Startup ();
VGui_Startup( glState.width, glState.height );
CL_ClearSpriteTextures(); // now all hud sprites are invalid
@ -754,4 +754,4 @@ void SCR_Shutdown( void )
UI_UnloadProgs();
scr_init = false;
}
}

View File

@ -361,7 +361,7 @@ void V_PostRender( void )
{
SCR_TileClear();
CL_DrawHUD( CL_ACTIVE );
VGui_Paint( true );
VGui_Paint();
}
switch( cls.scrshot_action )
@ -393,4 +393,4 @@ void V_PostRender( void )
SCR_MakeScreenShot();
R_AllowFog( true );
R_EndFrame();
}
}

View File

@ -13,14 +13,520 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#ifndef XASH_DEDICATED
#include "common.h"
#include "client.h"
#include "gl_local.h"
#include "vgui_draw.h"
#include "vgui_api.h"
#include "library.h"
#include <string.h>
#include "../keydefs.h"
convar_t *vgui_colorstrings;
int g_textures[VGUI_MAX_TEXTURES];
int g_textureId = 0;
int g_iBoundTexture;
static enum VGUI_KeyCode s_pVirtualKeyTrans[256];
static enum VGUI_DefaultCursor s_currentCursor;
#ifdef XASH_SDL
#include <SDL_events.h>
#include "platform/sdl/events.h"
static SDL_Cursor* s_pDefaultCursor[20];
#endif
static void *s_pVGuiSupport; // vgui_support library
void VGUI_DrawInit( void );
void VGUI_DrawShutdown( void );
void VGUI_SetupDrawingText( int *pColor );
void VGUI_SetupDrawingRect( int *pColor );
void VGUI_SetupDrawingImage( int *pColor );
void VGUI_BindTexture( int id );
void VGUI_EnableTexture( qboolean enable );
void VGUI_CreateTexture( int id, int width, int height );
void VGUI_UploadTexture( int id, const char *buffer, int width, int height );
void VGUI_UploadTextureBlock( int id, int drawX, int drawY, const byte *rgba, int blockWidth, int blockHeight );
void VGUI_DrawQuad( const vpoint_t *ul, const vpoint_t *lr );
void VGUI_GetTextureSizes( int *width, int *height );
int VGUI_GenerateTexture( void );
// Helper functions for vgui backend
/*void VGUI_HideCursor( void )
{
host.mouse_visible = false;
SDL_HideCursor();
}
void VGUI_ShowCursor( void )
{
host.mouse_visible = true;
SDL_ShowCursor();
}*/
void GAME_EXPORT *VGUI_EngineMalloc(size_t size)
{
return Z_Malloc( size );
}
qboolean GAME_EXPORT VGUI_IsInGame( void )
{
return cls.state == ca_active && cls.key_dest == key_game;
}
void GAME_EXPORT VGUI_GetMousePos( int *_x, int *_y )
{
float xscale = scr_width->value / (float)clgame.scrInfo.iWidth;
float yscale = scr_height->value / (float)clgame.scrInfo.iHeight;
int x, y;
CL_GetMousePosition( &x, &y );
*_x = x / xscale, *_y = y / yscale;
}
void VGUI_InitCursors( void )
{
// load up all default cursors
#ifdef XASH_SDL
s_pDefaultCursor[dc_none] = NULL;
s_pDefaultCursor[dc_arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
s_pDefaultCursor[dc_ibeam] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM);
s_pDefaultCursor[dc_hourglass]= SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT);
s_pDefaultCursor[dc_crosshair]= SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_CROSSHAIR);
s_pDefaultCursor[dc_up] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
s_pDefaultCursor[dc_sizenwse] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE);
s_pDefaultCursor[dc_sizenesw] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW);
s_pDefaultCursor[dc_sizewe] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE);
s_pDefaultCursor[dc_sizens] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS);
s_pDefaultCursor[dc_sizeall] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL);
s_pDefaultCursor[dc_no] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
s_pDefaultCursor[dc_hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
//host.mouse_visible = true;
SDL_SetCursor( s_pDefaultCursor[dc_arrow] );
#endif
}
void GAME_EXPORT VGUI_CursorSelect(enum VGUI_DefaultCursor cursor )
{
qboolean visible;
if( cls.key_dest != key_game || cl.refdef.paused )
return;
switch( cursor )
{
case dc_user:
case dc_none:
visible = false;
break;
default:
visible = true;
break;
}
#ifdef XASH_SDL
if( host.mouse_visible )
{
SDL_SetRelativeMouseMode( SDL_FALSE );
SDL_SetCursor( s_pDefaultCursor[cursor] );
SDL_ShowCursor( true );
}
else
{
SDL_ShowCursor( false );
if( host.mouse_visible )
SDL_GetRelativeMouseState( NULL, NULL );
}
//SDL_SetRelativeMouseMode(false);
#endif
if( s_currentCursor == cursor )
return;
s_currentCursor = cursor;
host.mouse_visible = visible;
}
byte GAME_EXPORT VGUI_GetColor( int i, int j)
{
return g_color_table[i][j];
}
// Define and initialize vgui API
void GAME_EXPORT VGUI_SetVisible( qboolean state )
{
host.mouse_visible=state;
#ifdef XASH_SDL
SDL_ShowCursor( state );
if( !state )
SDL_GetRelativeMouseState( NULL, NULL );
SDLash_EnableTextInput( state, true );
#endif
}
int GAME_EXPORT VGUI_UtfProcessChar( int in )
{
if( vgui_utf8->integer )
return Con_UtfProcessCharForce( in );
else
return in;
}
vguiapi_t vgui =
{
false, // Not initialized yet
VGUI_DrawInit,
VGUI_DrawShutdown,
VGUI_SetupDrawingText,
VGUI_SetupDrawingRect,
VGUI_SetupDrawingImage,
VGUI_BindTexture,
VGUI_EnableTexture,
VGUI_CreateTexture,
VGUI_UploadTexture,
VGUI_UploadTextureBlock,
VGUI_DrawQuad,
VGUI_GetTextureSizes,
VGUI_GenerateTexture,
VGUI_EngineMalloc,
/* VGUI_ShowCursor,
VGUI_HideCursor,*/
VGUI_CursorSelect,
VGUI_GetColor,
VGUI_IsInGame,
VGUI_SetVisible,
VGUI_GetMousePos,
VGUI_UtfProcessChar,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
};
qboolean VGui_IsActive( void )
{
return vgui.initialized;
}
/*
================
VGui_Startup
Load vgui_support library and call VGui_Startup
================
*/
void VGui_Startup( int width, int height )
{
static qboolean failed = false;
void (*F) ( vguiapi_t * );
char vguiloader[256];
char vguilib[256];
vguiloader[0] = vguilib[0] = '\0';
if( failed )
return;
if( !vgui.initialized )
{
#ifdef XASH_INTERNAL_GAMELIBS
s_pVGuiSupport = Com_LoadLibrary( "client", false );
if( s_pVGuiSupport )
{
F = Com_GetProcAddress( s_pVGuiSupport, "InitVGUISupportAPI" );
if( F )
{
F( &vgui );
vgui.initialized = true;
VGUI_InitCursors();
MsgDev( D_INFO, "vgui_support: found interal client support\n" );
}
}
#endif // XASH_INTERNAL_GAMELIBS
Com_ResetLibraryError();
// HACKHACK: load vgui with correct path first if specified.
// it will be reused while resolving vgui support and client deps
if( Sys_GetParmFromCmdLine( "-vguilib", vguilib ) )
{
if( Q_strstr( vguilib, ".dll") )
Q_strncpy( vguiloader, "vgui_support.dll", 256 );
else
Q_strncpy( vguiloader, VGUI_SUPPORT_DLL, 256 );
if( !Com_LoadLibrary( vguilib, false ) )
MsgDev( D_WARN, "VGUI preloading failed. Default library will be used!\n");
}
if( Q_strstr( GI->client_lib, ".dll" ) )
Q_strncpy( vguiloader, "vgui_support.dll", 256 );
if( !vguiloader[0] && !Sys_GetParmFromCmdLine( "-vguiloader", vguiloader ) )
Q_strncpy( vguiloader, VGUI_SUPPORT_DLL, 256 );
s_pVGuiSupport = Com_LoadLibrary( vguiloader, false );
if( !s_pVGuiSupport )
{
s_pVGuiSupport = Com_LoadLibrary( va( "../%s", vguiloader ), false );
}
if( !s_pVGuiSupport )
{
if( FS_SysFileExists( vguiloader, false ) )
MsgDev( D_ERROR, "Failed to load vgui_support library: %s", Com_GetLibraryError() );
else
MsgDev( D_INFO, "vgui_support: not found\n" );
}
else
{
F = Com_GetProcAddress( s_pVGuiSupport, "InitAPI" );
if( F )
{
F( &vgui );
vgui.initialized = true;
VGUI_InitCursors();
}
else
MsgDev( D_ERROR, "Failed to find vgui_support library entry point!\n" );
}
}
if( height < 480 )
height = 480;
if( width <= 640 )
width = 640;
else if( width <= 800 )
width = 800;
else if( width <= 1024 )
width = 1024;
else if( width <= 1152 )
width = 1152;
else if( width <= 1280 )
width = 1280;
else if( width <= 1600 )
width = 1600;
#ifdef DLL_LOADER
else if ( Q_strstr( vguiloader, ".dll" ) )
width = 1600;
#endif
if( vgui.initialized )
{
//host.mouse_visible = true;
vgui.Startup( width, height );
}
else failed = true;
}
/*
================
VGui_Shutdown
Unload vgui_support library and call VGui_Shutdown
================
*/
void VGui_Shutdown( void )
{
if( vgui.Shutdown )
vgui.Shutdown();
if( s_pVGuiSupport )
Com_FreeLibrary( s_pVGuiSupport );
s_pVGuiSupport = NULL;
vgui.initialized = false;
}
void VGUI_InitKeyTranslationTable( void )
{
static qboolean bInitted = false;
if( bInitted )
return;
bInitted = true;
// set virtual key translation table
Q_memset( s_pVirtualKeyTrans, -1, sizeof( s_pVirtualKeyTrans ) );
s_pVirtualKeyTrans['0'] = KEY_0;
s_pVirtualKeyTrans['1'] = KEY_1;
s_pVirtualKeyTrans['2'] = KEY_2;
s_pVirtualKeyTrans['3'] = KEY_3;
s_pVirtualKeyTrans['4'] = KEY_4;
s_pVirtualKeyTrans['5'] = KEY_5;
s_pVirtualKeyTrans['6'] = KEY_6;
s_pVirtualKeyTrans['7'] = KEY_7;
s_pVirtualKeyTrans['8'] = KEY_8;
s_pVirtualKeyTrans['9'] = KEY_9;
s_pVirtualKeyTrans['A'] = s_pVirtualKeyTrans['a'] = KEY_A;
s_pVirtualKeyTrans['B'] = s_pVirtualKeyTrans['b'] = KEY_B;
s_pVirtualKeyTrans['C'] = s_pVirtualKeyTrans['c'] = KEY_C;
s_pVirtualKeyTrans['D'] = s_pVirtualKeyTrans['d'] = KEY_D;
s_pVirtualKeyTrans['E'] = s_pVirtualKeyTrans['e'] = KEY_E;
s_pVirtualKeyTrans['F'] = s_pVirtualKeyTrans['f'] = KEY_F;
s_pVirtualKeyTrans['G'] = s_pVirtualKeyTrans['g'] = KEY_G;
s_pVirtualKeyTrans['H'] = s_pVirtualKeyTrans['h'] = KEY_H;
s_pVirtualKeyTrans['I'] = s_pVirtualKeyTrans['i'] = KEY_I;
s_pVirtualKeyTrans['J'] = s_pVirtualKeyTrans['j'] = KEY_J;
s_pVirtualKeyTrans['K'] = s_pVirtualKeyTrans['k'] = KEY_K;
s_pVirtualKeyTrans['L'] = s_pVirtualKeyTrans['l'] = KEY_L;
s_pVirtualKeyTrans['M'] = s_pVirtualKeyTrans['m'] = KEY_M;
s_pVirtualKeyTrans['N'] = s_pVirtualKeyTrans['n'] = KEY_N;
s_pVirtualKeyTrans['O'] = s_pVirtualKeyTrans['o'] = KEY_O;
s_pVirtualKeyTrans['P'] = s_pVirtualKeyTrans['p'] = KEY_P;
s_pVirtualKeyTrans['Q'] = s_pVirtualKeyTrans['q'] = KEY_Q;
s_pVirtualKeyTrans['R'] = s_pVirtualKeyTrans['r'] = KEY_R;
s_pVirtualKeyTrans['S'] = s_pVirtualKeyTrans['s'] = KEY_S;
s_pVirtualKeyTrans['T'] = s_pVirtualKeyTrans['t'] = KEY_T;
s_pVirtualKeyTrans['U'] = s_pVirtualKeyTrans['u'] = KEY_U;
s_pVirtualKeyTrans['V'] = s_pVirtualKeyTrans['v'] = KEY_V;
s_pVirtualKeyTrans['W'] = s_pVirtualKeyTrans['w'] = KEY_W;
s_pVirtualKeyTrans['X'] = s_pVirtualKeyTrans['x'] = KEY_X;
s_pVirtualKeyTrans['Y'] = s_pVirtualKeyTrans['y'] = KEY_Y;
s_pVirtualKeyTrans['Z'] = s_pVirtualKeyTrans['z'] = KEY_Z;
s_pVirtualKeyTrans[K_KP_5 - 5] = KEY_PAD_0;
s_pVirtualKeyTrans[K_KP_5 - 4] = KEY_PAD_1;
s_pVirtualKeyTrans[K_KP_5 - 3] = KEY_PAD_2;
s_pVirtualKeyTrans[K_KP_5 - 2] = KEY_PAD_3;
s_pVirtualKeyTrans[K_KP_5 - 1] = KEY_PAD_4;
s_pVirtualKeyTrans[K_KP_5 - 0] = KEY_PAD_5;
s_pVirtualKeyTrans[K_KP_5 + 1] = KEY_PAD_6;
s_pVirtualKeyTrans[K_KP_5 + 2] = KEY_PAD_7;
s_pVirtualKeyTrans[K_KP_5 + 3] = KEY_PAD_8;
s_pVirtualKeyTrans[K_KP_5 + 4] = KEY_PAD_9;
s_pVirtualKeyTrans[K_KP_SLASH] = KEY_PAD_DIVIDE;
s_pVirtualKeyTrans['*'] = KEY_PAD_MULTIPLY;
s_pVirtualKeyTrans[K_KP_MINUS] = KEY_PAD_MINUS;
s_pVirtualKeyTrans[K_KP_PLUS] = KEY_PAD_PLUS;
s_pVirtualKeyTrans[K_KP_ENTER] = KEY_PAD_ENTER;
//s_pVirtualKeyTrans[K_KP_DECIMAL] = KEY_PAD_DECIMAL;
s_pVirtualKeyTrans['['] = KEY_LBRACKET;
s_pVirtualKeyTrans[']'] = KEY_RBRACKET;
s_pVirtualKeyTrans[';'] = KEY_SEMICOLON;
s_pVirtualKeyTrans['\''] = KEY_APOSTROPHE;
s_pVirtualKeyTrans['`'] = KEY_BACKQUOTE;
s_pVirtualKeyTrans[','] = KEY_COMMA;
s_pVirtualKeyTrans['.'] = KEY_PERIOD;
s_pVirtualKeyTrans[K_KP_SLASH] = KEY_SLASH;
s_pVirtualKeyTrans['\\'] = KEY_BACKSLASH;
s_pVirtualKeyTrans['-'] = KEY_MINUS;
s_pVirtualKeyTrans['='] = KEY_EQUAL;
s_pVirtualKeyTrans[K_ENTER] = KEY_ENTER;
s_pVirtualKeyTrans[K_SPACE] = KEY_SPACE;
s_pVirtualKeyTrans[K_BACKSPACE] = KEY_BACKSPACE;
s_pVirtualKeyTrans[K_TAB] = KEY_TAB;
s_pVirtualKeyTrans[K_CAPSLOCK] = KEY_CAPSLOCK;
s_pVirtualKeyTrans[K_KP_NUMLOCK] = KEY_NUMLOCK;
s_pVirtualKeyTrans[K_ESCAPE] = KEY_ESCAPE;
//s_pVirtualKeyTrans[K_KP_SCROLLLOCK] = KEY_SCROLLLOCK;
s_pVirtualKeyTrans[K_INS] = KEY_INSERT;
s_pVirtualKeyTrans[K_DEL] = KEY_DELETE;
s_pVirtualKeyTrans[K_HOME] = KEY_HOME;
s_pVirtualKeyTrans[K_END] = KEY_END;
s_pVirtualKeyTrans[K_PGUP] = KEY_PAGEUP;
s_pVirtualKeyTrans[K_PGDN] = KEY_PAGEDOWN;
s_pVirtualKeyTrans[K_PAUSE] = KEY_BREAK;
//s_pVirtualKeyTrans[K_SHIFT] = KEY_RSHIFT;
s_pVirtualKeyTrans[K_SHIFT] = KEY_LSHIFT; // SHIFT -> left SHIFT
//s_pVirtualKeyTrans[SDLK_RALT] = KEY_RALT;
s_pVirtualKeyTrans[K_ALT] = KEY_LALT; // ALT -> left ALT
//s_pVirtualKeyTrans[SDLK_RCTRL] = KEY_RCONTROL;
s_pVirtualKeyTrans[K_CTRL] = KEY_LCONTROL; // CTRL -> left CTRL
s_pVirtualKeyTrans[K_WIN] = KEY_LWIN;
//s_pVirtualKeyTrans[SDLK_APPLICATION] = KEY_RWIN;
//s_pVirtualKeyTrans[K_WIN] = KEY_APP;
s_pVirtualKeyTrans[K_UPARROW] = KEY_UP;
s_pVirtualKeyTrans[K_LEFTARROW] = KEY_LEFT;
s_pVirtualKeyTrans[K_DOWNARROW] = KEY_DOWN;
s_pVirtualKeyTrans[K_RIGHTARROW] = KEY_RIGHT;
s_pVirtualKeyTrans[K_F1] = KEY_F1;
s_pVirtualKeyTrans[K_F2] = KEY_F2;
s_pVirtualKeyTrans[K_F3] = KEY_F3;
s_pVirtualKeyTrans[K_F4] = KEY_F4;
s_pVirtualKeyTrans[K_F5] = KEY_F5;
s_pVirtualKeyTrans[K_F6] = KEY_F6;
s_pVirtualKeyTrans[K_F7] = KEY_F7;
s_pVirtualKeyTrans[K_F8] = KEY_F8;
s_pVirtualKeyTrans[K_F9] = KEY_F9;
s_pVirtualKeyTrans[K_F10] = KEY_F10;
s_pVirtualKeyTrans[K_F11] = KEY_F11;
s_pVirtualKeyTrans[K_F12] = KEY_F12;
}
enum VGUI_KeyCode VGUI_MapKey( int keyCode )
{
VGUI_InitKeyTranslationTable();
if( keyCode < 0 || keyCode >= (int)sizeof( s_pVirtualKeyTrans ) / (int)sizeof( s_pVirtualKeyTrans[0] ))
{
//Assert( false );
return (enum VGUI_KeyCode)-1;
}
else
{
return s_pVirtualKeyTrans[keyCode];
}
}
void VGui_KeyEvent( int key, int down )
{
if( !vgui.initialized )
return;
#ifdef XASH_SDL
if( host.mouse_visible )
SDLash_EnableTextInput( 1, false );
#endif
switch( key )
{
case K_MOUSE1:
vgui.Mouse( down?MA_PRESSED:MA_RELEASED, MOUSE_LEFT );
return;
case K_MOUSE2:
vgui.Mouse( down?MA_PRESSED:MA_RELEASED, MOUSE_RIGHT );
return;
case K_MOUSE3:
vgui.Mouse( down?MA_PRESSED:MA_RELEASED, MOUSE_MIDDLE );
return;
case K_MWHEELDOWN:
vgui.Mouse( MA_WHEEL, 1 );
return;
case K_MWHEELUP:
vgui.Mouse( MA_WHEEL, -1 );
return;
default:
break;
}
if( down == 2 )
vgui.Key( KA_TYPED, VGUI_MapKey( key ) );
else
vgui.Key( down?KA_PRESSED:KA_RELEASED, VGUI_MapKey( key ) );
//Msg("VGui_KeyEvent %d %d %d\n", key, VGUI_MapKey( key ), down );
}
void VGui_MouseMove( int x, int y )
{
float xscale = scr_width->value / (float)clgame.scrInfo.iWidth;
float yscale = scr_height->value / (float)clgame.scrInfo.iHeight;
if( vgui.initialized )
vgui.MouseMove( x / xscale, y / yscale );
}
/*
================
@ -29,22 +535,20 @@ VGUI_DrawInit
Startup VGUI backend
================
*/
void VGUI_DrawInit( void )
void GAME_EXPORT VGUI_DrawInit( void )
{
memset( g_textures, 0, sizeof( g_textures ));
g_textureId = 0;
vgui_colorstrings = Cvar_Get( "vgui_colorstrings", "0", FCVAR_ARCHIVE, "allow colorstrings in VGUI texts" );
Q_memset( g_textures, 0, sizeof( g_textures ));
g_textureId = g_iBoundTexture = 0;
}
/*
================
VGUI_DrawShutdown
Release all the textures
Release all textures
================
*/
void VGUI_DrawShutdown( void )
void GAME_EXPORT VGUI_DrawShutdown( void )
{
int i;
@ -61,10 +565,10 @@ VGUI_GenerateTexture
generate unique texture number
================
*/
int VGUI_GenerateTexture( void )
int GAME_EXPORT VGUI_GenerateTexture( void )
{
if( ++g_textureId >= VGUI_MAX_TEXTURES )
Host_Error( "VGUI_GenerateTexture: VGUI_MAX_TEXTURES limit exceeded\n" );
Sys_Error( "VGUI_GenerateTexture: VGUI_MAX_TEXTURES limit exceeded\n" );
return g_textureId;
}
@ -75,7 +579,7 @@ VGUI_UploadTexture
Upload texture into video memory
================
*/
void VGUI_UploadTexture( int id, const char *buffer, int width, int height )
void GAME_EXPORT VGUI_UploadTexture( int id, const char *buffer, int width, int height )
{
rgbdata_t r_image;
char texName[32];
@ -87,7 +591,7 @@ void VGUI_UploadTexture( int id, const char *buffer, int width, int height )
}
Q_snprintf( texName, sizeof( texName ), "*vgui%i", id );
memset( &r_image, 0, sizeof( r_image ));
Q_memset( &r_image, 0, sizeof( r_image ));
r_image.width = width;
r_image.height = height;
@ -97,16 +601,56 @@ void VGUI_UploadTexture( int id, const char *buffer, int width, int height )
r_image.buffer = (byte *)buffer;
g_textures[id] = GL_LoadTextureInternal( texName, &r_image, TF_IMAGE, false );
GL_SetTextureType( g_textures[id], TEX_VGUI );
g_iBoundTexture = id;
}
/*
================
VGUI_SetupDrawingRect
VGUI_CreateTexture
setup transparency etc
Create empty rgba texture and upload them into video memory
================
*/
void VGUI_SetupDrawingRect( int *pColor )
void GAME_EXPORT VGUI_CreateTexture( int id, int width, int height )
{
rgbdata_t r_image;
char texName[32];
if( id <= 0 || id >= VGUI_MAX_TEXTURES )
{
MsgDev( D_ERROR, "VGUI_CreateTexture: bad texture %i. Ignored\n", id );
return;
}
Q_snprintf( texName, sizeof( texName ), "*vgui%i", id );
Q_memset( &r_image, 0, sizeof( r_image ));
r_image.width = width;
r_image.height = height;
r_image.type = PF_RGBA_32;
r_image.size = r_image.width * r_image.height * 4;
r_image.flags = IMAGE_HAS_ALPHA;
r_image.buffer = NULL;
g_textures[id] = GL_LoadTextureInternal( texName, &r_image, TF_IMAGE|TF_NEAREST, false );
GL_SetTextureType( g_textures[id], TEX_VGUI );
g_iBoundTexture = id;
}
void GAME_EXPORT VGUI_UploadTextureBlock( int id, int drawX, int drawY, const byte *rgba, int blockWidth, int blockHeight )
{
if( id <= 0 || id >= VGUI_MAX_TEXTURES || g_textures[id] == 0 || g_textures[id] == cls.fillImage )
{
MsgDev( D_ERROR, "VGUI_UploadTextureBlock: bad texture %i. Ignored\n", id );
return;
}
pglTexSubImage2D( GL_TEXTURE_2D, 0, drawX, drawY, blockWidth, blockHeight, GL_RGBA, GL_UNSIGNED_BYTE, rgba );
g_iBoundTexture = id;
}
void GAME_EXPORT VGUI_SetupDrawingRect( int *pColor )
{
pglEnable( GL_BLEND );
pglDisable( GL_ALPHA_TEST );
@ -114,42 +658,62 @@ void VGUI_SetupDrawingRect( int *pColor )
pglColor4ub( pColor[0], pColor[1], pColor[2], 255 - pColor[3] );
}
/*
================
VGUI_SetupDrawingImage
setup transparency etc
================
*/
void VGUI_SetupDrawingImage( int *pColor )
void GAME_EXPORT VGUI_SetupDrawingText( int *pColor )
{
pglEnable( GL_BLEND );
pglEnable( GL_ALPHA_TEST );
pglAlphaFunc( GL_GREATER, 0.0f );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglColor4ub( pColor[0], pColor[1], pColor[2], 255 - pColor[3] );
}
/*
================
VGUI_BindTexture
void GAME_EXPORT VGUI_SetupDrawingImage( int *pColor )
{
pglEnable( GL_BLEND );
pglEnable( GL_ALPHA_TEST );
pglAlphaFunc( GL_GREATER, 0.0f );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglColor4ub( pColor[0], pColor[1], pColor[2], 255 - pColor[3] );
}
bind VGUI texture through private index
================
*/
void VGUI_BindTexture( int id )
void GAME_EXPORT VGUI_BindTexture( int id )
{
if( id > 0 && id < VGUI_MAX_TEXTURES && g_textures[id] )
{
GL_Bind( GL_TEXTURE0, g_textures[id] );
GL_Bind( XASH_TEXTURE0, g_textures[id] );
g_iBoundTexture = id;
}
else
{
// NOTE: same as bogus index 2700 in GoldSrc
GL_Bind( GL_TEXTURE0, g_textures[1] );
id = g_iBoundTexture = 1;
GL_Bind( XASH_TEXTURE0, g_textures[id] );
}
}
/*
================
VGUI_GetTextureSizes
returns wide and tall for currently binded texture
================
*/
void GAME_EXPORT VGUI_GetTextureSizes( int *width, int *height )
{
gltexture_t *glt;
int texnum;
if( g_iBoundTexture )
texnum = g_textures[g_iBoundTexture];
else texnum = tr.defaultTexture;
glt = R_GetTexture( texnum );
if( width ) *width = glt->srcWidth;
if( height ) *height = glt->srcHeight;
}
/*
================
VGUI_EnableTexture
@ -157,7 +721,7 @@ VGUI_EnableTexture
disable texturemode for fill rectangle
================
*/
void VGUI_EnableTexture( qboolean enable )
void GAME_EXPORT VGUI_EnableTexture( qboolean enable )
{
if( enable ) pglEnable( GL_TEXTURE_2D );
else pglDisable( GL_TEXTURE_2D );
@ -170,49 +734,44 @@ VGUI_DrawQuad
generic method to fill rectangle
================
*/
void VGUI_DrawQuad( const vpoint_t *ul, const vpoint_t *lr )
void GAME_EXPORT VGUI_DrawQuad( const vpoint_t *ul, const vpoint_t *lr )
{
float xscale = scr_width->value / (float)clgame.scrInfo.iWidth;
float yscale = scr_height->value / (float)clgame.scrInfo.iHeight;
ASSERT( ul != NULL && lr != NULL );
pglBegin( GL_QUADS );
pglTexCoord2f( ul->coord[0], ul->coord[1] );
pglVertex2f( ul->point[0], ul->point[1] );
pglVertex2f( ul->point[0] * xscale, ul->point[1] * yscale );
pglTexCoord2f( lr->coord[0], ul->coord[1] );
pglVertex2f( lr->point[0], ul->point[1] );
pglVertex2f( lr->point[0] * xscale, ul->point[1] * yscale );
pglTexCoord2f( lr->coord[0], lr->coord[1] );
pglVertex2f( lr->point[0], lr->point[1] );
pglVertex2f( lr->point[0] * xscale, lr->point[1] * yscale );
pglTexCoord2f( ul->coord[0], lr->coord[1] );
pglVertex2f( ul->point[0], lr->point[1] );
pglVertex2f( ul->point[0] * xscale, lr->point[1] * yscale );
pglEnd();
}
/*
================
VGUI_DrawBuffer
render the quads array
================
*/
void VGUI_DrawBuffer( const vpoint_t *buffer, int numVerts )
void VGui_Paint()
{
if( numVerts <= 0 ) return;
if(vgui.initialized)
vgui.Paint();
}
pglEnable( GL_BLEND );
pglEnable( GL_ALPHA_TEST );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
void VGui_RunFrame()
{
//stub
}
pglEnableClientState( GL_VERTEX_ARRAY );
pglEnableClientState( GL_TEXTURE_COORD_ARRAY );
pglEnableClientState( GL_COLOR_ARRAY );
pglTexCoordPointer( 2, GL_FLOAT, sizeof( vpoint_t ), &buffer->coord[0] );
pglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( vpoint_t ), &buffer->color[0] );
pglVertexPointer( 2, GL_FLOAT, sizeof( vpoint_t ), &buffer->point[0] );
pglDrawArrays( GL_QUADS, 0, numVerts );
pglDisableClientState( GL_VERTEX_ARRAY );
pglDisableClientState( GL_TEXTURE_COORD_ARRAY );
pglDisableClientState( GL_COLOR_ARRAY );
}
void *GAME_EXPORT VGui_GetPanel()
{
if( vgui.initialized )
return vgui.GetPanel();
return NULL;
}
#endif

View File

@ -20,58 +20,22 @@ GNU General Public License for more details.
extern "C" {
#endif
#include "port.h"
#define VGUI_MAX_TEXTURES 2048 // a half of total textures count
extern rgba_t g_color_table[8]; // for colored strings support
extern convar_t *vgui_colorstrings;
// VGUI generic vertex
typedef struct
{
vec2_t point;
vec2_t coord;
byte color[4];
} vpoint_t;
//
// vgui_backend.c
// vgui_draw.c
//
void VGUI_DrawInit( void );
void VGUI_DrawShutdown( void );
void VGUI_SetupDrawingRect( int *pColor );
void VGUI_SetupDrawingImage( int *pColor );
void VGUI_BindTexture( int id );
void VGUI_EnableTexture( qboolean enable );
void VGUI_UploadTexture( int id, const char *buffer, int width, int height );
LONG VGUI_SurfaceWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
void VGUI_DrawQuad( const vpoint_t *ul, const vpoint_t *lr );
void VGUI_DrawBuffer( const vpoint_t *buffer, int numVerts );
int VGUI_GenerateTexture( void );
void *VGui_GetPanel( void );
#ifdef __cplusplus
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 );
#endif
//
// gl_vidnt.c
//
qboolean R_DescribeVIDMode( int width, int height );
//
// vgui_int.c
//
void VGui_Startup( void );
void VGui_Startup( int width, int height );
void VGui_Shutdown( void );
void *VGui_GetPanel( void );
void VGui_Paint( int paintAll );
void VGui_RunFrame( void );
void VGui_ViewportPaintBackground( int extents[4] );
void VGui_Paint();
void VGui_RunFrame();
void VGui_KeyEvent( int key, int down );
void VGui_MouseMove( int x, int y );
qboolean VGui_IsActive( void );
void *VGui_GetPanel();
#ifdef __cplusplus
}
#endif
#endif//VGUI_DRAW_H
#endif//VGUI_DRAW_H

View File

@ -1,290 +0,0 @@
/*
vgui_input.cpp - handle kb & mouse
Copyright (C) 2011 Uncle Mike
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.
*/
#define OEMRESOURCE // for OCR_* cursor junk
#include "common.h"
#include "client.h"
#include "vgui_draw.h"
#include "vgui_main.h"
#include "input.h"
static KeyCode s_pVirtualKeyTrans[256];
static HICON s_pDefaultCursor[20];
static HICON s_hCurrentCursor = NULL;
void VGUI_InitCursors( void )
{
// load up all default cursors
s_pDefaultCursor[Cursor::dc_none] = NULL;
s_pDefaultCursor[Cursor::dc_arrow] = (HICON)LoadCursor( NULL, (LPCTSTR)OCR_NORMAL );
s_pDefaultCursor[Cursor::dc_ibeam] = (HICON)LoadCursor( NULL, (LPCTSTR)OCR_IBEAM );
s_pDefaultCursor[Cursor::dc_hourglass]= (HICON)LoadCursor( NULL, (LPCTSTR)OCR_WAIT );
s_pDefaultCursor[Cursor::dc_crosshair]= (HICON)LoadCursor( NULL, (LPCTSTR)OCR_CROSS );
s_pDefaultCursor[Cursor::dc_up] = (HICON)LoadCursor( NULL, (LPCTSTR)OCR_UP );
s_pDefaultCursor[Cursor::dc_sizenwse] = (HICON)LoadCursor( NULL, (LPCTSTR)OCR_SIZENWSE );
s_pDefaultCursor[Cursor::dc_sizenesw] = (HICON)LoadCursor( NULL, (LPCTSTR)OCR_SIZENESW );
s_pDefaultCursor[Cursor::dc_sizewe] = (HICON)LoadCursor( NULL, (LPCTSTR)OCR_SIZEWE );
s_pDefaultCursor[Cursor::dc_sizens] = (HICON)LoadCursor( NULL, (LPCTSTR)OCR_SIZENS );
s_pDefaultCursor[Cursor::dc_sizeall] = (HICON)LoadCursor( NULL, (LPCTSTR)OCR_SIZEALL );
s_pDefaultCursor[Cursor::dc_no] = (HICON)LoadCursor( NULL, (LPCTSTR)OCR_NO );
s_pDefaultCursor[Cursor::dc_hand] = (HICON)LoadCursor( NULL, (LPCTSTR)32649 );
s_hCurrentCursor = s_pDefaultCursor[Cursor::dc_arrow];
host.mouse_visible = true;
}
void VGUI_CursorSelect( Cursor *cursor )
{
Assert( cursor != NULL );
host.mouse_visible = true;
switch( cursor->getDefaultCursor( ))
{
case Cursor::dc_user:
case Cursor::dc_none:
host.mouse_visible = false;
break;
case Cursor::dc_arrow:
case Cursor::dc_ibeam:
case Cursor::dc_hourglass:
case Cursor::dc_crosshair:
case Cursor::dc_up:
case Cursor::dc_sizenwse:
case Cursor::dc_sizenesw:
case Cursor::dc_sizewe:
case Cursor::dc_sizens:
case Cursor::dc_sizeall:
case Cursor::dc_no:
case Cursor::dc_hand:
s_hCurrentCursor = s_pDefaultCursor[cursor->getDefaultCursor()];
break;
default:
host.mouse_visible = false;
Assert( 0 );
break;
}
VGUI_ActivateCurrentCursor();
}
void VGUI_ActivateCurrentCursor( void )
{
if( cls.key_dest != key_game || cl.paused )
return;
if( host.mouse_visible )
{
while( ShowCursor( true ) < 0 );
SetCursor( s_hCurrentCursor );
}
else
{
while( ShowCursor( false ) >= 0 );
SetCursor( NULL );
}
}
void VGUI_InitKeyTranslationTable( void )
{
static bool bInitted = false;
if( bInitted ) return;
bInitted = true;
// set virtual key translation table
memset( s_pVirtualKeyTrans, -1, sizeof( s_pVirtualKeyTrans ));
s_pVirtualKeyTrans['0'] = KEY_0;
s_pVirtualKeyTrans['1'] = KEY_1;
s_pVirtualKeyTrans['2'] = KEY_2;
s_pVirtualKeyTrans['3'] = KEY_3;
s_pVirtualKeyTrans['4'] = KEY_4;
s_pVirtualKeyTrans['5'] = KEY_5;
s_pVirtualKeyTrans['6'] = KEY_6;
s_pVirtualKeyTrans['7'] = KEY_7;
s_pVirtualKeyTrans['8'] = KEY_8;
s_pVirtualKeyTrans['9'] = KEY_9;
s_pVirtualKeyTrans['A'] = s_pVirtualKeyTrans['a'] = KEY_A;
s_pVirtualKeyTrans['B'] = s_pVirtualKeyTrans['b'] = KEY_B;
s_pVirtualKeyTrans['C'] = s_pVirtualKeyTrans['c'] = KEY_C;
s_pVirtualKeyTrans['D'] = s_pVirtualKeyTrans['d'] = KEY_D;
s_pVirtualKeyTrans['E'] = s_pVirtualKeyTrans['e'] = KEY_E;
s_pVirtualKeyTrans['F'] = s_pVirtualKeyTrans['f'] = KEY_F;
s_pVirtualKeyTrans['G'] = s_pVirtualKeyTrans['g'] = KEY_G;
s_pVirtualKeyTrans['H'] = s_pVirtualKeyTrans['h'] = KEY_H;
s_pVirtualKeyTrans['I'] = s_pVirtualKeyTrans['i'] = KEY_I;
s_pVirtualKeyTrans['J'] = s_pVirtualKeyTrans['j'] = KEY_J;
s_pVirtualKeyTrans['K'] = s_pVirtualKeyTrans['k'] = KEY_K;
s_pVirtualKeyTrans['L'] = s_pVirtualKeyTrans['l'] = KEY_L;
s_pVirtualKeyTrans['M'] = s_pVirtualKeyTrans['m'] = KEY_M;
s_pVirtualKeyTrans['N'] = s_pVirtualKeyTrans['n'] = KEY_N;
s_pVirtualKeyTrans['O'] = s_pVirtualKeyTrans['o'] = KEY_O;
s_pVirtualKeyTrans['P'] = s_pVirtualKeyTrans['p'] = KEY_P;
s_pVirtualKeyTrans['Q'] = s_pVirtualKeyTrans['q'] = KEY_Q;
s_pVirtualKeyTrans['R'] = s_pVirtualKeyTrans['r'] = KEY_R;
s_pVirtualKeyTrans['S'] = s_pVirtualKeyTrans['s'] = KEY_S;
s_pVirtualKeyTrans['T'] = s_pVirtualKeyTrans['t'] = KEY_T;
s_pVirtualKeyTrans['U'] = s_pVirtualKeyTrans['u'] = KEY_U;
s_pVirtualKeyTrans['V'] = s_pVirtualKeyTrans['v'] = KEY_V;
s_pVirtualKeyTrans['W'] = s_pVirtualKeyTrans['w'] = KEY_W;
s_pVirtualKeyTrans['X'] = s_pVirtualKeyTrans['x'] = KEY_X;
s_pVirtualKeyTrans['Y'] = s_pVirtualKeyTrans['y'] = KEY_Y;
s_pVirtualKeyTrans['Z'] = s_pVirtualKeyTrans['z'] = KEY_Z;
s_pVirtualKeyTrans[VK_NUMPAD0] = KEY_PAD_0;
s_pVirtualKeyTrans[VK_NUMPAD1] = KEY_PAD_1;
s_pVirtualKeyTrans[VK_NUMPAD2] = KEY_PAD_2;
s_pVirtualKeyTrans[VK_NUMPAD3] = KEY_PAD_3;
s_pVirtualKeyTrans[VK_NUMPAD4] = KEY_PAD_4;
s_pVirtualKeyTrans[VK_NUMPAD5] = KEY_PAD_5;
s_pVirtualKeyTrans[VK_NUMPAD6] = KEY_PAD_6;
s_pVirtualKeyTrans[VK_NUMPAD7] = KEY_PAD_7;
s_pVirtualKeyTrans[VK_NUMPAD8] = KEY_PAD_8;
s_pVirtualKeyTrans[VK_NUMPAD9] = KEY_PAD_9;
s_pVirtualKeyTrans[VK_DIVIDE] = KEY_PAD_DIVIDE;
s_pVirtualKeyTrans[VK_MULTIPLY] = KEY_PAD_MULTIPLY;
s_pVirtualKeyTrans[VK_SUBTRACT] = KEY_PAD_MINUS;
s_pVirtualKeyTrans[VK_ADD] = KEY_PAD_PLUS;
s_pVirtualKeyTrans[VK_RETURN] = KEY_PAD_ENTER;
s_pVirtualKeyTrans[VK_DECIMAL] = KEY_PAD_DECIMAL;
s_pVirtualKeyTrans[0xdb] = KEY_LBRACKET;
s_pVirtualKeyTrans[0xdd] = KEY_RBRACKET;
s_pVirtualKeyTrans[0xba] = KEY_SEMICOLON;
s_pVirtualKeyTrans[0xde] = KEY_APOSTROPHE;
s_pVirtualKeyTrans[0xc0] = KEY_BACKQUOTE;
s_pVirtualKeyTrans[0xbc] = KEY_COMMA;
s_pVirtualKeyTrans[0xbe] = KEY_PERIOD;
s_pVirtualKeyTrans[0xbf] = KEY_SLASH;
s_pVirtualKeyTrans[0xdc] = KEY_BACKSLASH;
s_pVirtualKeyTrans[0xbd] = KEY_MINUS;
s_pVirtualKeyTrans[0xbb] = KEY_EQUAL;
s_pVirtualKeyTrans[VK_RETURN] = KEY_ENTER;
s_pVirtualKeyTrans[VK_SPACE] = KEY_SPACE;
s_pVirtualKeyTrans[VK_BACK] = KEY_BACKSPACE;
s_pVirtualKeyTrans[VK_TAB] = KEY_TAB;
s_pVirtualKeyTrans[VK_CAPITAL] = KEY_CAPSLOCK;
s_pVirtualKeyTrans[VK_NUMLOCK] = KEY_NUMLOCK;
s_pVirtualKeyTrans[VK_ESCAPE] = KEY_ESCAPE;
s_pVirtualKeyTrans[VK_SCROLL] = KEY_SCROLLLOCK;
s_pVirtualKeyTrans[VK_INSERT] = KEY_INSERT;
s_pVirtualKeyTrans[VK_DELETE] = KEY_DELETE;
s_pVirtualKeyTrans[VK_HOME] = KEY_HOME;
s_pVirtualKeyTrans[VK_END] = KEY_END;
s_pVirtualKeyTrans[VK_PRIOR] = KEY_PAGEUP;
s_pVirtualKeyTrans[VK_NEXT] = KEY_PAGEDOWN;
s_pVirtualKeyTrans[VK_PAUSE] = KEY_BREAK;
s_pVirtualKeyTrans[VK_SHIFT] = KEY_RSHIFT;
s_pVirtualKeyTrans[VK_SHIFT] = KEY_LSHIFT; // SHIFT -> left SHIFT
s_pVirtualKeyTrans[VK_MENU] = KEY_RALT;
s_pVirtualKeyTrans[VK_MENU] = KEY_LALT; // ALT -> left ALT
s_pVirtualKeyTrans[VK_CONTROL] = KEY_RCONTROL;
s_pVirtualKeyTrans[VK_CONTROL] = KEY_LCONTROL; // CTRL -> left CTRL
s_pVirtualKeyTrans[VK_LWIN] = KEY_LWIN;
s_pVirtualKeyTrans[VK_RWIN] = KEY_RWIN;
s_pVirtualKeyTrans[VK_APPS] = KEY_APP;
s_pVirtualKeyTrans[VK_UP] = KEY_UP;
s_pVirtualKeyTrans[VK_LEFT] = KEY_LEFT;
s_pVirtualKeyTrans[VK_DOWN] = KEY_DOWN;
s_pVirtualKeyTrans[VK_RIGHT] = KEY_RIGHT;
s_pVirtualKeyTrans[VK_F1] = KEY_F1;
s_pVirtualKeyTrans[VK_F2] = KEY_F2;
s_pVirtualKeyTrans[VK_F3] = KEY_F3;
s_pVirtualKeyTrans[VK_F4] = KEY_F4;
s_pVirtualKeyTrans[VK_F5] = KEY_F5;
s_pVirtualKeyTrans[VK_F6] = KEY_F6;
s_pVirtualKeyTrans[VK_F7] = KEY_F7;
s_pVirtualKeyTrans[VK_F8] = KEY_F8;
s_pVirtualKeyTrans[VK_F9] = KEY_F9;
s_pVirtualKeyTrans[VK_F10] = KEY_F10;
s_pVirtualKeyTrans[VK_F11] = KEY_F11;
s_pVirtualKeyTrans[VK_F12] = KEY_F12;
}
KeyCode VGUI_MapKey( int keyCode )
{
VGUI_InitKeyTranslationTable();
if( keyCode < 0 || keyCode >= ARRAYSIZE( s_pVirtualKeyTrans ))
{
Assert( 0 );
return (KeyCode)-1;
}
else
{
return s_pVirtualKeyTrans[keyCode];
}
}
LONG VGUI_SurfaceWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
if( !engSurface )
return 0;
switch( uMsg )
{
case WM_SETCURSOR:
VGUI_ActivateCurrentCursor();
break;
case WM_MOUSEMOVE:
engApp->internalCursorMoved((short)LOWORD( lParam ), (short)HIWORD( lParam ), engSurface );
break;
case WM_LBUTTONDOWN:
engApp->internalMousePressed( MOUSE_LEFT, engSurface );
break;
case WM_RBUTTONDOWN:
engApp->internalMousePressed( MOUSE_RIGHT, engSurface );
break;
case WM_MBUTTONDOWN:
engApp->internalMousePressed( MOUSE_MIDDLE, engSurface );
break;
case WM_LBUTTONUP:
engApp->internalMouseReleased( MOUSE_LEFT, engSurface );
break;
case WM_RBUTTONUP:
engApp->internalMouseReleased( MOUSE_RIGHT, engSurface );
break;
case WM_MBUTTONUP:
engApp->internalMouseReleased( MOUSE_MIDDLE, engSurface );
break;
case WM_LBUTTONDBLCLK:
engApp->internalMouseDoublePressed( MOUSE_LEFT, engSurface );
break;
case WM_RBUTTONDBLCLK:
engApp->internalMouseDoublePressed( MOUSE_RIGHT, engSurface );
break;
case WM_MBUTTONDBLCLK:
engApp->internalMouseDoublePressed( MOUSE_MIDDLE, engSurface );
break;
case WM_MOUSEWHEEL:
engApp->internalMouseWheeled(((short)HIWORD( wParam )) / WHEEL_DELTA, engSurface );
break;
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
if( !FBitSet( lParam, BIT( 30 )))
engApp->internalKeyPressed( VGUI_MapKey( wParam ), engSurface );
engApp->internalKeyTyped( VGUI_MapKey( wParam ), engSurface );
break;
case WM_CHAR:
case WM_SYSCHAR:
// already handled in Key_Event
break;
case WM_KEYUP:
case WM_SYSKEYUP:
engApp->internalKeyReleased( VGUI_MapKey( wParam ), engSurface );
break;
}
return 1;
}

View File

@ -1,129 +0,0 @@
/*
vgui_int.cpp - vgui dll interaction
Copyright (C) 2011 Uncle Mike
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.
*/
#include "common.h"
#include "client.h"
#include "const.h"
#include "vgui_draw.h"
#include "vgui_main.h"
Panel *rootPanel = NULL;
CEngineSurface *engSurface = NULL;
CEngineApp staticApp, *engApp;
void CEngineApp :: setCursorPos( int x, int y )
{
POINT pt;
pt.x = x;
pt.y = y;
ClientToScreen( (HWND)host.hWnd, &pt );
::SetCursorPos( pt.x, pt.y );
}
void CEngineApp :: getCursorPos( int &x,int &y )
{
POINT pt;
// find mouse movement
::GetCursorPos( &pt );
ScreenToClient((HWND)host.hWnd, &pt );
x = pt.x;
y = pt.y;
}
void VGui_RunFrame( void )
{
if( GetModuleHandle( "fraps32.dll" ) || GetModuleHandle( "fraps64.dll" ))
host.force_draw_version = true;
else host.force_draw_version = false;
}
void VGui_SetRootPanelSize( void )
{
if( rootPanel != NULL )
rootPanel->setBounds( 0, 0, gameui.globals->scrWidth, gameui.globals->scrHeight );
}
void VGui_Startup( void )
{
if( engSurface ) return;
engApp = (CEngineApp *)App::getInstance();
engApp->reset();
engApp->setMinimumTickMillisInterval( 0 ); // paint every frame
rootPanel = new Panel( 0, 0, 320, 240 ); // size will be changed in VGui_SetRootPanelSize
rootPanel->setPaintBorderEnabled( false );
rootPanel->setPaintBackgroundEnabled( false );
rootPanel->setPaintEnabled( false );
rootPanel->setCursor( engApp->getScheme()->getCursor( Scheme::scu_none ));
engSurface = new CEngineSurface( rootPanel );
VGui_SetRootPanelSize ();
VGUI_DrawInit ();
}
void VGui_Shutdown( void )
{
delete rootPanel;
delete engSurface;
engSurface = NULL;
rootPanel = NULL;
}
void VGui_Paint( int paintAll )
{
int extents[4];
if( cls.state != ca_active || !rootPanel )
return;
VGui_SetRootPanelSize ();
rootPanel->repaint();
EnableScissor( true );
if( cls.key_dest == key_game )
{
App::getInstance()->externalTick();
}
if( paintAll )
{
// paint everything
rootPanel->paintTraverse();
}
else
{
rootPanel->getAbsExtents( extents[0], extents[1], extents[2], extents[3] );
VGui_ViewportPaintBackground( extents );
}
EnableScissor( false );
}
void VGui_ViewportPaintBackground( int extents[4] )
{
// Msg( "Vgui_ViewportPaintBackground( %i, %i, %i, %i )\n", extents[0], extents[1], extents[2], extents[3] );
}
void *VGui_GetPanel( void )
{
return (void *)rootPanel;
}

View File

@ -1,117 +0,0 @@
/*
vgui_main.h - vgui main header
Copyright (C) 2011 Uncle Mike
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.
*/
#ifndef VGUI_MAIN_H
#define VGUI_MAIN_H
#include<VGUI.h>
#include<VGUI_App.h>
#include<VGUI_Font.h>
#include<VGUI_Panel.h>
#include<VGUI_Cursor.h>
#include<VGUI_SurfaceBase.h>
#include<VGUI_InputSignal.h>
#include<VGUI_MouseCode.h>
#include<VGUI_KeyCode.h>
using namespace vgui;
struct PaintStack
{
Panel *m_pPanel;
int iTranslateX;
int iTranslateY;
int iScissorLeft;
int iScissorRight;
int iScissorTop;
int iScissorBottom;
};
class CEngineSurface : public SurfaceBase
{
private:
void InitVertex( vpoint_t &vertex, int x, int y, float u, float v );
public:
CEngineSurface( Panel *embeddedPanel );
~CEngineSurface();
public:
// not used in engine instance
virtual bool setFullscreenMode( int wide, int tall, int bpp ) { return false; }
virtual void setWindowedMode( void ) { }
virtual void setTitle( const char *title ) { }
virtual void createPopup( Panel* embeddedPanel ) { }
virtual bool isWithin( int x, int y ) { return true; }
void SetupPaintState( const PaintStack *paintState );
#ifdef NEW_VGUI_DLL
virtual void GetMousePos( int &x, int &y ) { }
#endif
virtual bool hasFocus( void ) { return true; }
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 void drawPrintChar( int x, int y, int wide, int tall, float s0, float t0, float s1, float t1, int color[4] );
virtual void addCharToBuffer( const vpoint_t *ul, const vpoint_t *lr, int color[4] );
virtual void setCursor( Cursor* cursor );
virtual void pushMakeCurrent( Panel* panel, bool useInsets );
virtual void popMakeCurrent( Panel* panel );
// not used in engine instance
virtual bool createPlat( void ) { return false; }
virtual bool recreateContext( void ) { return false; }
virtual void enableMouseCapture( bool state ) { }
virtual void invalidate( Panel *panel ) { }
virtual void setAsTopMost( bool state ) { }
virtual void applyChanges( void ) { }
virtual void swapBuffers( void ) { }
virtual void flushBuffer( void );
protected:
int _drawTextPos[2];
int _drawColor[4];
int _drawTextColor[4];
int _translateX, _translateY;
int _currentTexture;
};
// initialize VGUI::App as external (part of engine)
class CEngineApp : public App
{
public:
virtual void main( int argc, char* argv[] ) { }
virtual void setCursorPos( int x, int y ); // we need to recompute abs position to window
virtual void getCursorPos( int &x,int &y );
protected:
virtual void platTick(void) { }
};
extern Panel *rootPanel;
extern CEngineSurface *engSurface;
extern CEngineApp *engApp;
//
// vgui_input.cpp
//
void VGUI_InitCursors( void );
void VGUI_CursorSelect( Cursor *cursor );
void VGUI_ActivateCurrentCursor( void );
#endif//VGUI_MAIN_H

View File

@ -1,465 +0,0 @@
/*
vgui_surf.cpp - main vgui layer
Copyright (C) 2011 Uncle Mike
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.
*/
#include "common.h"
#include "client.h"
#include "vgui_draw.h"
#include "vgui_main.h"
#define MAXVERTEXBUFFERS 1024
#define MAX_PAINT_STACK 8
#define FONT_SIZE 512
#define FONT_PAGES 8
static char staticRGBA[FONT_SIZE * FONT_SIZE * 4];
static vpoint_t g_VertexBuffer[MAXVERTEXBUFFERS];
static int g_iVertexBufferEntriesUsed = 0;
static int staticContextCount = 0;
struct FontInfo
{
int id;
int pageCount;
int pageForChar[256];
int bindIndex[FONT_PAGES];
float texCoord[256][FONT_PAGES];
int contextCount;
};
static Font* staticFont = NULL;
static FontInfo* staticFontInfo;
static Dar<FontInfo*> staticFontInfoDar;
static PaintStack paintStack[MAX_PAINT_STACK];
static staticPaintStackPos = 0;
CEngineSurface :: CEngineSurface( Panel *embeddedPanel ):SurfaceBase( embeddedPanel )
{
_drawTextColor[0] = _drawTextColor[1] = _drawTextColor[2] = _drawTextColor[3] = 255;
_drawColor[0] = _drawColor[1] = _drawColor[2] = _drawColor[3] = 255;
_drawTextPos[0] = _drawTextPos[1] = _currentTexture = 0;
staticFont = NULL;
staticFontInfo = NULL;
staticFontInfoDar.setCount( 0 );
staticPaintStackPos = 0;
staticContextCount++;
VGUI_InitCursors ();
}
CEngineSurface :: ~CEngineSurface( void )
{
VGUI_DrawShutdown ();
}
void CEngineSurface :: setCursor( Cursor *cursor )
{
_currentCursor = cursor;
VGUI_CursorSelect( cursor );
}
void CEngineSurface :: SetupPaintState( const PaintStack *paintState )
{
_translateX = paintState->iTranslateX;
_translateY = paintState->iTranslateY;
SetScissorRect( paintState->iScissorLeft, paintState->iScissorTop, paintState->iScissorRight, paintState->iScissorBottom );
}
void CEngineSurface :: InitVertex( vpoint_t &vertex, int x, int y, float u, float v )
{
vertex.point[0] = x + _translateX;
vertex.point[1] = y + _translateY;
vertex.coord[0] = u;
vertex.coord[1] = v;
}
int CEngineSurface :: createNewTextureID( void )
{
return VGUI_GenerateTexture();
}
void CEngineSurface :: drawSetColor( int r, int g, int b, int a )
{
_drawColor[0] = r;
_drawColor[1] = g;
_drawColor[2] = b;
_drawColor[3] = a;
}
void CEngineSurface :: drawSetTextColor( int r, int g, int b, int a )
{
_drawTextColor[0] = r;
_drawTextColor[1] = g;
_drawTextColor[2] = b;
_drawTextColor[3] = a;
}
void CEngineSurface :: drawFilledRect( int x0, int y0, int x1, int y1 )
{
vpoint_t rect[2];
vpoint_t clippedRect[2];
if( _drawColor[3] >= 255 ) return;
InitVertex( rect[0], x0, y0, 0, 0 );
InitVertex( rect[1], x1, y1, 0, 0 );
// fully clipped?
if( !ClipRect( rect[0], rect[1], &clippedRect[0], &clippedRect[1] ))
return;
VGUI_SetupDrawingRect( _drawColor );
VGUI_EnableTexture( false );
VGUI_DrawQuad( &clippedRect[0], &clippedRect[1] );
VGUI_EnableTexture( true );
}
void CEngineSurface :: drawOutlinedRect( int x0, int y0, int x1, int y1 )
{
if( _drawColor[3] >= 255 ) return;
drawFilledRect( x0, y0, x1, y0 + 1 ); // top
drawFilledRect( x0, y1 - 1, x1, y1 ); // bottom
drawFilledRect( x0, y0 + 1, x0 + 1, y1 - 1 ); // left
drawFilledRect( x1 - 1, y0 + 1, x1, y1 - 1 ); // right
}
void CEngineSurface :: drawSetTextFont( Font *font )
{
staticFont = font;
if( font )
{
bool buildFont = false;
staticFontInfo = NULL;
for( int i = 0; i < staticFontInfoDar.getCount(); i++ )
{
if( staticFontInfoDar[i]->id == font->getId( ))
{
staticFontInfo = staticFontInfoDar[i];
if( staticFontInfo->contextCount != staticContextCount )
buildFont = true;
}
}
if( !staticFontInfo || buildFont )
{
staticFontInfo = new FontInfo;
staticFontInfo->id = 0;
staticFontInfo->pageCount = 0;
staticFontInfo->bindIndex[0] = 0;
staticFontInfo->bindIndex[1] = 0;
staticFontInfo->bindIndex[2] = 0;
staticFontInfo->bindIndex[3] = 0;
memset( staticFontInfo->pageForChar, 0, sizeof( staticFontInfo->pageForChar ));
staticFontInfo->contextCount = -1;
staticFontInfo->id = staticFont->getId();
staticFontInfoDar.putElement( staticFontInfo );
staticFontInfo->contextCount = staticContextCount;
int currentPage = 0;
int x = 0, y = 0;
memset( staticRGBA, 0, sizeof( staticRGBA ));
for( int i = 0; i < 256; i++ )
{
int abcA, abcB, abcC;
staticFont->getCharABCwide( i, abcA, abcB, abcC );
int wide = abcB;
if( isspace( i )) continue;
int tall = staticFont->getTall();
if( x + wide + 1 > FONT_SIZE )
{
x = 0;
y += tall + 1;
}
if( y + tall + 1 > FONT_SIZE )
{
if( !staticFontInfo->bindIndex[currentPage] )
{
int bindIndex = createNewTextureID();
staticFontInfo->bindIndex[currentPage] = bindIndex;
}
drawSetTextureRGBA( staticFontInfo->bindIndex[currentPage], staticRGBA, FONT_SIZE, FONT_SIZE );
currentPage++;
if( currentPage == FONT_PAGES )
break;
memset( staticRGBA, 0, sizeof( staticRGBA ));
x = y = 0;
}
staticFont->getCharRGBA( i, x, y, FONT_SIZE, FONT_SIZE, (byte *)staticRGBA );
staticFontInfo->pageForChar[i] = currentPage;
staticFontInfo->texCoord[i][0] = (float)((double)x / (double)FONT_SIZE );
staticFontInfo->texCoord[i][1] = (float)((double)y / (double)FONT_SIZE );
staticFontInfo->texCoord[i][2] = (float)((double)(x + wide)/(double)FONT_SIZE );
staticFontInfo->texCoord[i][3] = (float)((double)(y + tall)/(double)FONT_SIZE );
x += wide + 1;
}
if( currentPage != FONT_PAGES )
{
if( !staticFontInfo->bindIndex[currentPage] )
{
int bindIndex = createNewTextureID();
staticFontInfo->bindIndex[currentPage] = bindIndex;
}
drawSetTextureRGBA( staticFontInfo->bindIndex[currentPage], staticRGBA, FONT_SIZE, FONT_SIZE );
}
staticFontInfo->pageCount = currentPage + 1;
}
}
}
void CEngineSurface :: drawSetTextPos( int x, int y )
{
_drawTextPos[0] = x;
_drawTextPos[1] = y;
}
void CEngineSurface :: addCharToBuffer( const vpoint_t *ul, const vpoint_t *lr, int color[4] )
{
if( g_iVertexBufferEntriesUsed >= MAXVERTEXBUFFERS )
flushBuffer();
g_VertexBuffer[g_iVertexBufferEntriesUsed + 0].coord[0] = ul->coord[0];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 0].coord[1] = ul->coord[1];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 0].point[0] = ul->point[0];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 0].point[1] = ul->point[1];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 0].color[0] = color[0];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 0].color[1] = color[1];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 0].color[2] = color[2];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 0].color[3] = 255 - color[3];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 1].coord[0] = lr->coord[0];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 1].coord[1] = ul->coord[1];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 1].point[0] = lr->point[0];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 1].point[1] = ul->point[1];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 1].color[0] = color[0];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 1].color[1] = color[1];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 1].color[2] = color[2];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 1].color[3] = 255 - color[3];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 2].coord[0] = lr->coord[0];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 2].coord[1] = lr->coord[1];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 2].point[0] = lr->point[0];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 2].point[1] = lr->point[1];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 2].color[0] = color[0];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 2].color[1] = color[1];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 2].color[2] = color[2];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 2].color[3] = 255 - color[3];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 3].coord[0] = ul->coord[0];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 3].coord[1] = lr->coord[1];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 3].point[0] = ul->point[0];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 3].point[1] = lr->point[1];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 3].color[0] = color[0];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 3].color[1] = color[1];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 3].color[2] = color[2];
g_VertexBuffer[g_iVertexBufferEntriesUsed + 3].color[3] = 255 - color[3];
g_iVertexBufferEntriesUsed += 4;
}
void CEngineSurface :: flushBuffer( void )
{
if( g_iVertexBufferEntriesUsed <= 0 )
return;
VGUI_DrawBuffer( g_VertexBuffer, g_iVertexBufferEntriesUsed );
g_iVertexBufferEntriesUsed = 0;
}
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;
ul.point[0] = x;
ul.point[1] = y;
lr.point[0] = x + wide;
lr.point[1] = y + tall;
// gets at the texture coords for this character in its texture page
ul.coord[0] = s0;
ul.coord[1] = t0;
lr.coord[0] = s1;
lr.coord[1] = t1;
vpoint_t clippedRect[2];
if( !ClipRect( ul, lr, &clippedRect[0], &clippedRect[1] ))
return;
#if 1
// TESTTEST: needs to be more tested
addCharToBuffer( &clippedRect[0], &clippedRect[1], color );
#else
VGUI_SetupDrawingImage( color );
VGUI_DrawQuad( &clippedRect[0], &clippedRect[1] ); // draw the letter
#endif
}
void CEngineSurface :: drawPrintText( const char *text, int textLen )
{
static bool hasColor = 0;
static int numColor = 7;
if( !text || !staticFont || !staticFontInfo )
return;
int x = _drawTextPos[0] + _translateX;
int y = _drawTextPos[1] + _translateY;
int tall = staticFont->getTall();
int curTextColor[4];
// HACKHACK: allow color strings in VGUI
if( numColor != 7 && vgui_colorstrings->value )
{
for( int j = 0; j < 3; j++ ) // grab predefined color
curTextColor[j] = g_color_table[numColor][j];
}
else
{
for( int j = 0; j < 3; j++ ) // revert default color
curTextColor[j] = _drawTextColor[j];
}
curTextColor[3] = _drawTextColor[3]; // copy alpha
if( textLen == 1 && vgui_colorstrings->value )
{
if( *text == '^' )
{
hasColor = true;
return; // skip '^'
}
else if( hasColor && isdigit( *text ))
{
numColor = ColorIndex( *text );
hasColor = false; // handled
return; // skip colornum
}
else hasColor = false;
}
for( int i = 0; i < textLen; i++ )
{
int abcA, abcB, abcC;
int curCh = (byte)text[i];
staticFont->getCharABCwide( curCh, abcA, abcB, abcC );
float s0 = staticFontInfo->texCoord[curCh][0];
float t0 = staticFontInfo->texCoord[curCh][1];
float s1 = staticFontInfo->texCoord[curCh][2];
float t1 = staticFontInfo->texCoord[curCh][3];
int wide = abcB;
drawSetTexture( staticFontInfo->bindIndex[staticFontInfo->pageForChar[curCh]] );
drawPrintChar( x, y, wide, tall, s0, t0, s1, t1, curTextColor );
x += abcA + abcB + abcC;
}
_drawTextPos[0] += x;
}
void CEngineSurface :: drawSetTextureRGBA( int id, const char* rgba, int wide, int tall )
{
VGUI_UploadTexture( id, rgba, wide, tall );
_currentTexture = id;
}
void CEngineSurface :: drawSetTexture( int id )
{
if( _currentTexture != id )
{
_currentTexture = id;
flushBuffer();
}
VGUI_BindTexture( id );
}
void CEngineSurface :: drawTexturedRect( int x0, int y0, int x1, int y1 )
{
vpoint_t rect[2];
vpoint_t clippedRect[2];
InitVertex( rect[0], x0, y0, 0, 0 );
InitVertex( rect[1], x1, y1, 1, 1 );
// fully clipped?
if( !ClipRect( rect[0], rect[1], &clippedRect[0], &clippedRect[1] ))
return;
VGUI_SetupDrawingImage( _drawColor );
VGUI_DrawQuad( &clippedRect[0], &clippedRect[1] );
}
void CEngineSurface :: pushMakeCurrent( Panel* panel, bool useInsets )
{
int insets[4] = { 0, 0, 0, 0 };
int absExtents[4];
int clipRect[4];
if( useInsets )
panel->getInset( insets[0], insets[1], insets[2], insets[3] );
panel->getAbsExtents( absExtents[0], absExtents[1], absExtents[2], absExtents[3] );
panel->getClipRect( clipRect[0], clipRect[1], clipRect[2], clipRect[3] );
PaintStack *paintState = &paintStack[staticPaintStackPos];
ASSERT( staticPaintStackPos < MAX_PAINT_STACK );
paintState->m_pPanel = panel;
// determine corrected top left origin
paintState->iTranslateX = insets[0] + absExtents[0];
paintState->iTranslateY = insets[1] + absExtents[1];
// setup clipping rectangle for scissoring
paintState->iScissorLeft = clipRect[0];
paintState->iScissorTop = clipRect[1];
paintState->iScissorRight = clipRect[2];
paintState->iScissorBottom = clipRect[3];
SetupPaintState( paintState );
staticPaintStackPos++;
}
void CEngineSurface :: popMakeCurrent( Panel *panel )
{
flushBuffer();
int top = staticPaintStackPos - 1;
// more pops that pushes?
Assert( top >= 0 );
// didn't pop in reverse order of push?
Assert( paintStack[top].m_pPanel == panel );
staticPaintStackPos--;
if( top > 0 ) SetupPaintState( &paintStack[top-1] );
}

View File

@ -110,6 +110,12 @@ XASH SPECIFIC - sort of hack that works only in Xash3D not in GoldSrc
#define IsColorString( p ) ( p && *( p ) == '^' && *(( p ) + 1) && *(( p ) + 1) >= '0' && *(( p ) + 1 ) <= '9' )
#define ColorIndex( c ) ((( c ) - '0' ) & 7 )
#if defined __i386__ && defined __GNUC__
#define GAME_EXPORT __attribute__((force_align_arg_pointer))
#else
#define GAME_EXPORT
#endif
typedef unsigned long dword;
typedef unsigned int uint;
typedef char string[MAX_STRING];

View File

@ -156,7 +156,7 @@ static void IN_ActivateCursor( void )
}
}
void IN_SetCursor( HICON hCursor )
void IN_SetCursor( void *hCursor )
{
in_mousecursor = hCursor;
@ -338,6 +338,8 @@ void IN_MouseMove( void )
GetCursorPos( &current_pos );
ScreenToClient( host.hWnd, &current_pos );
VGui_MouseMove( current_pos.x, current_pos.y );
// if the menu is visible, move the menu cursor
UI_MouseMove( current_pos.x, current_pos.y );
@ -435,153 +437,3 @@ void Host_InputFrame( void )
IN_ActivateMouse( false );
IN_MouseMove();
}
/*
====================
IN_WndProc
main window procedure
====================
*/
LONG IN_WndProc( HWND hWnd, UINT uMsg, UINT wParam, LONG lParam )
{
int i, temp = 0;
qboolean fActivate;
if( uMsg == in_mouse_wheel )
uMsg = WM_MOUSEWHEEL;
VGUI_SurfaceWndProc( hWnd, uMsg, wParam, lParam );
switch( uMsg )
{
case WM_KILLFOCUS:
if( Cvar_VariableInteger( "fullscreen" ))
ShowWindow( host.hWnd, SW_SHOWMINNOACTIVE );
break;
case WM_SETCURSOR:
IN_ActivateCursor();
break;
case WM_MOUSEWHEEL:
if( !in_mouseactive )
break;
if(( short )HIWORD( wParam ) > 0 )
{
Key_Event( K_MWHEELUP, true );
Key_Event( K_MWHEELUP, false );
}
else
{
Key_Event( K_MWHEELDOWN, true );
Key_Event( K_MWHEELDOWN, false );
}
break;
case WM_CREATE:
host.hWnd = hWnd;
GetWindowRect( host.hWnd, &real_rect );
RegisterHotKey( host.hWnd, PRINTSCREEN_ID, 0, VK_SNAPSHOT );
break;
case WM_CLOSE:
Sys_Quit();
break;
case WM_ACTIVATE:
if( host.status == HOST_SHUTDOWN )
break; // no need to activate
if( HIWORD( wParam ))
host.status = HOST_SLEEP;
else if( LOWORD( wParam ) == WA_INACTIVE )
host.status = HOST_NOFOCUS;
else host.status = HOST_FRAME;
fActivate = (host.status == HOST_FRAME) ? true : false;
wnd_caption = GetSystemMetrics( SM_CYCAPTION ) + WND_BORDER;
S_Activate( fActivate, host.hWnd );
IN_ActivateMouse( fActivate );
Key_ClearStates();
if( host.status == HOST_FRAME )
{
SetForegroundWindow( hWnd );
ShowWindow( hWnd, SW_RESTORE );
}
else if( Cvar_VariableInteger( "fullscreen" ))
{
ShowWindow( hWnd, SW_MINIMIZE );
}
break;
case WM_MOVE:
if( !Cvar_VariableInteger( "fullscreen" ))
{
RECT rect;
int xPos, yPos, style;
xPos = (short)LOWORD( lParam ); // horizontal position
yPos = (short)HIWORD( lParam ); // vertical position
rect.left = rect.top = 0;
rect.right = rect.bottom = 1;
style = GetWindowLong( hWnd, GWL_STYLE );
AdjustWindowRect( &rect, style, FALSE );
Cvar_SetValue( "_window_xpos", xPos + rect.left );
Cvar_SetValue( "_window_ypos", yPos + rect.top );
GetWindowRect( host.hWnd, &real_rect );
}
break;
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
case WM_XBUTTONDOWN:
case WM_XBUTTONUP:
case WM_MOUSEMOVE:
for( i = 0; i < in_mouse_buttons; i++ )
{
if( wParam & mouse_buttons[i] )
temp |= (1<<i);
}
IN_MouseEvent( temp );
break;
case WM_SYSCOMMAND:
// never turn screensaver while Xash is active
if( wParam == SC_SCREENSAVE && host.status != HOST_SLEEP )
return 0;
break;
case WM_SYSKEYDOWN:
if( wParam == VK_RETURN )
{
// alt+enter fullscreen switch
Cvar_SetValue( "fullscreen", !Cvar_VariableValue( "fullscreen" ));
return 0;
}
// intentional fallthrough
case WM_KEYDOWN:
Key_Event( Host_MapKey( lParam ), true );
if( Host_MapKey( lParam ) == K_ALT )
return 0; // prevent WC_SYSMENU call
break;
case WM_SYSKEYUP:
case WM_KEYUP:
Key_Event( Host_MapKey( lParam ), false );
break;
case WM_CHAR:
CL_CharEvent( wParam );
break;
case WM_HOTKEY:
switch( LOWORD( wParam ))
{
case PRINTSCREEN_ID:
// anti FiEctro system: prevent to write snapshot without Xash version
Q_strncpy( cls.shotname, "clipboard.bmp", sizeof( cls.shotname ));
cls.scrshot_action = scrshot_snapshot; // build new frame for screenshot
host.write_to_clipboard = true;
cls.envshot_vieworg = NULL;
break;
}
break;
}
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}

View File

@ -48,7 +48,6 @@ void IN_DeactivateMouse( void );
void IN_MouseSavePos( void );
void IN_MouseRestorePos( void );
void IN_ToggleClientMouse( int newstate, int oldstate );
LONG IN_WndProc( HWND hWnd, UINT uMsg, UINT wParam, LONG lParam );
void IN_SetCursor( HICON hCursor );
void IN_SetCursor( void *hCursor );
#endif//INPUT_H
#endif//INPUT_H

View File

@ -16,6 +16,7 @@ GNU General Public License for more details.
#include "common.h"
#include "input.h"
#include "client.h"
#include "vgui_draw.h"
typedef struct key_s
{
@ -542,6 +543,8 @@ void Key_Event( int key, qboolean down )
keys[key].repeats = 0;
}
VGui_KeyEvent( key, down );
// console key is hardcoded, so the user can never unbind it
if( key == '`' || key == '~' )
{
@ -763,4 +766,4 @@ void CL_CharEvent( int key )
{
UI_CharEvent( key );
}
}
}

215
engine/vgui_api.h Normal file
View File

@ -0,0 +1,215 @@
/*
vgui_api.h - vgui_support library interface
Copyright (C) 2015 Mittorn
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.
*/
#ifndef VGUI_API_H
#define VGUI_API_H
#include "xash3d_types.h"
// VGUI generic vertex
typedef struct
{
vec2_t point;
vec2_t coord;
} vpoint_t;
// C-Style VGUI enums
enum VGUI_MouseCode
{
MOUSE_LEFT=0,
MOUSE_RIGHT,
MOUSE_MIDDLE,
MOUSE_LAST
};
enum VGUI_KeyCode
{
KEY_0=0,
KEY_1,
KEY_2,
KEY_3,
KEY_4,
KEY_5,
KEY_6,
KEY_7,
KEY_8,
KEY_9,
KEY_A,
KEY_B,
KEY_C,
KEY_D,
KEY_E,
KEY_F,
KEY_G,
KEY_H,
KEY_I,
KEY_J,
KEY_K,
KEY_L,
KEY_M,
KEY_N,
KEY_O,
KEY_P,
KEY_Q,
KEY_R,
KEY_S,
KEY_T,
KEY_U,
KEY_V,
KEY_W,
KEY_X,
KEY_Y,
KEY_Z,
KEY_PAD_0,
KEY_PAD_1,
KEY_PAD_2,
KEY_PAD_3,
KEY_PAD_4,
KEY_PAD_5,
KEY_PAD_6,
KEY_PAD_7,
KEY_PAD_8,
KEY_PAD_9,
KEY_PAD_DIVIDE,
KEY_PAD_MULTIPLY,
KEY_PAD_MINUS,
KEY_PAD_PLUS,
KEY_PAD_ENTER,
KEY_PAD_DECIMAL,
KEY_LBRACKET,
KEY_RBRACKET,
KEY_SEMICOLON,
KEY_APOSTROPHE,
KEY_BACKQUOTE,
KEY_COMMA,
KEY_PERIOD,
KEY_SLASH,
KEY_BACKSLASH,
KEY_MINUS,
KEY_EQUAL,
KEY_ENTER,
KEY_SPACE,
KEY_BACKSPACE,
KEY_TAB,
KEY_CAPSLOCK,
KEY_NUMLOCK,
KEY_ESCAPE,
KEY_SCROLLLOCK,
KEY_INSERT,
KEY_DELETE,
KEY_HOME,
KEY_END,
KEY_PAGEUP,
KEY_PAGEDOWN,
KEY_BREAK,
KEY_LSHIFT,
KEY_RSHIFT,
KEY_LALT,
KEY_RALT,
KEY_LCONTROL,
KEY_RCONTROL,
KEY_LWIN,
KEY_RWIN,
KEY_APP,
KEY_UP,
KEY_LEFT,
KEY_DOWN,
KEY_RIGHT,
KEY_F1,
KEY_F2,
KEY_F3,
KEY_F4,
KEY_F5,
KEY_F6,
KEY_F7,
KEY_F8,
KEY_F9,
KEY_F10,
KEY_F11,
KEY_F12,
KEY_LAST
};
enum VGUI_KeyAction
{
KA_TYPED=0,
KA_PRESSED,
KA_RELEASED
};
enum VGUI_MouseAction
{
MA_PRESSED=0,
MA_RELEASED,
MA_DOUBLE,
MA_WHEEL
};
enum VGUI_DefaultCursor
{
dc_user,
dc_none,
dc_arrow,
dc_ibeam,
dc_hourglass,
dc_crosshair,
dc_up,
dc_sizenwse,
dc_sizenesw,
dc_sizewe,
dc_sizens,
dc_sizeall,
dc_no,
dc_hand,
dc_last
};
typedef struct vguiapi_s
{
qboolean initialized;
void (*DrawInit)( void );
void (*DrawShutdown)( void );
void (*SetupDrawingText)( int *pColor );
void (*SetupDrawingRect)( int *pColor );
void (*SetupDrawingImage)( int *pColor );
void (*BindTexture)( int id );
void (*EnableTexture)( qboolean enable );
void (*CreateTexture)( int id, int width, int height );
void (*UploadTexture)( int id, const char *buffer, int width, int height );
void (*UploadTextureBlock)( int id, int drawX, int drawY, const byte *rgba, int blockWidth, int blockHeight );
void (*DrawQuad)( const vpoint_t *ul, const vpoint_t *lr );
void (*GetTextureSizes)( int *width, int *height );
int (*GenerateTexture)( void );
void *(*EngineMalloc)( size_t size );
void (*CursorSelect)( enum VGUI_DefaultCursor cursor );
byte (*GetColor)( int i, int j );
qboolean (*IsInGame)( void );
void (*SetVisible)( qboolean state );
void (*GetCursorPos)( int *x, int *y );
int (*ProcessUtfChar)( int ch );
void (*Startup)( int width, int height );
void (*Shutdown)( void );
void *(*GetPanel)( void );
void (*Paint)( void );
void (*Mouse)(enum VGUI_MouseAction action, int code );
void (*Key)(enum VGUI_KeyAction action,enum VGUI_KeyCode code );
void (*MouseMove)( int x, int y );
} vguiapi_t;
#endif // VGUI_API_H

23
vgui_support/Android.mk Normal file
View File

@ -0,0 +1,23 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE = vgui_support
include $(XASH3D_CONFIG)
LOCAL_CFLAGS = -fsigned-char -DVGUI_TOUCH_SCROLL -DNO_STL -DXASH_GLES -DINTERNAL_VGUI_SUPPORT -Wall -Wextra -Wno-unused-parameter -Wno-unused-variable
LOCAL_CPPFLAGS = -frtti -fno-exceptions -Wno-write-strings -Wno-invalid-offsetof -std=gnu++98
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/../common \
$(LOCAL_PATH)/../engine \
$(HLSDK_PATH)/utils/vgui/include \
$(VGUI_DIR)/include
LOCAL_SRC_FILES := vgui_clip.cpp vgui_font.cpp vgui_input.cpp vgui_int.cpp vgui_surf.cpp
LOCAL_STATIC_LIBRARIES := vgui
include $(BUILD_STATIC_LIBRARY)

View File

@ -0,0 +1,89 @@
#
# Copyright (c) 2015 Pavlo Lavrenenko
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
cmake_minimum_required(VERSION 2.8.0)
project(VGUI_SUPPORT)
set(VGUI_SUPPORT vgui_support)
fwgs_fix_default_msvc_settings()
cmake_dependent_option(VGUI_SUPPORT_OLD_VGUI_BINARY "Build against old version of VGUI, from HLSDK2.3" OFF "MSVC" OFF)
if(NOT MINGW)
file(GLOB VGUI_SUPPORT_SOURCES *.cpp *.c)
else()
# Download prebuilt VGUI_support, as there is no way to have same C++ ABI for VC++ and MinGW.
# Also there is no way to have a target without source code, so let's just have custom install() rule
# Prebuilt VGUI support is downloaded from github.com/FWGS/vgui_support_bin
set(FORCE_UNPACK FALSE)
message(STATUS "Downloading prebuilt vgui_support for MinGW... See vgui_support/CMakeLists.txt for details")
if(NOT EXISTS ${CMAKE_BINARY_DIR}/vgui_support.zip)
file(DOWNLOAD https://github.com/FWGS/vgui_support_bin/archive/master.zip ${CMAKE_BINARY_DIR}/vgui_support.zip)
set(FORCE_UNPACK TRUE)
endif()
if(NOT EXISTS ${CMAKE_BINARY_DIR}/vgui_support_prebuilt)
set(FORCE_UNPACK TRUE)
endif()
if(FORCE_UNPACK)
fwgs_unpack_file(${CMAKE_BINARY_DIR}/vgui_support.zip vgui_support_prebuilt)
endif()
# HACKHACK: create empty target
execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/u_cant_touch_this.cpp)
set(VGUI_SUPPORT_SOURCES ${CMAKE_BINARY_DIR}/u_cant_touch_this.cpp)
endif()
include_directories( . ../common ../engine ../engine/common ../engine/client ../engine/client/vgui )
add_library(${VGUI_SUPPORT} SHARED ${VGUI_SUPPORT_SOURCES})
set(VGUI_BRANCH "master")
if(VGUI_SUPPORT_OLD_VGUI_BINARY)
set(VGUI_BRANCH "pre-2013")
endif()
fwgs_library_dependency(${VGUI_SUPPORT} VGUI
"https://github.com/FWGS/vgui-dev/archive/${VGUI_BRANCH}.zip" "VGUI.zip" "HL_SDK_DIR" "vgui-dev-${VGUI_BRANCH}")
if(MSVC)
string(REGEX REPLACE "lib$" "dll" VGUI_DLL "${VGUI_LIBRARY}")
install(FILES ${VGUI_DLL}
CONFIGURATIONS Debug
DESTINATION ${LIB_INSTALL_DIR}/Debug/)
install(FILES ${VGUI_DLL}
CONFIGURATIONS Release
DESTINATION ${LIB_INSTALL_DIR}/Release/)
endif()
fwgs_set_default_properties(${VGUI_SUPPORT})
if(NOT MINGW)
fwgs_install(${VGUI_SUPPORT})
if(NOT WIN32 AND NOT XASH_NO_INSTALL_VGUI_BIN)
install(FILES ${VGUI_LIBRARY} DESTINATION ${LIB_INSTALL_DIR}/${LIB_INSTALL_SUBDIR}
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
endif()
else()
# Use prebuilt.
# TODO: this allows only HLSDK 2.4 VGUI
install(FILES ${CMAKE_BINARY_DIR}/vgui_support_prebuilt/vgui_support_bin-master/vgui_support.dll
DESTINATION ${LIB_INSTALL_DIR}/${LIB_INSTALL_SUBDIR})
endif()

View File

@ -0,0 +1,29 @@
CC ?= gcc -m32
CXX ?= g++ -m32 -std=gnu++98
CFLAGS ?= -O2 -ggdb -fPIC
TOPDIR = $(PWD)/..
VGUI_DIR ?= ./vgui-dev
INCLUDES = -I../common -I../engine -I../engine/common -I../engine/client -I../engine/client/vgui -I../pm_shared
INCLUDES += -I$(VGUI_DIR)/include/
DEFINES = -DNO_STL
%.o : %.cpp
$(CXX) $(CFLAGS) $(INCLUDES) $(DEFINES) -c $< -o $@
SRCS = $(wildcard *.cpp)
OBJS = $(SRCS:.cpp=.o)
libvgui_support.so : $(OBJS)
$(CXX) $(LDFLAGS) -o libvgui_support.so -shared $(OBJS) vgui.so
.PHONY: depend clean
clean :
$(RM) $(OBJS) libvgui_support.so
depend: Makefile.dep
Makefile.dep: $(SRCS)
rm -f ./Makefile.dep
$(CC) $(CFLAGS) $(INCLUDES) $(DEFINES) -MM $^>>./Makefile.dep
include Makefile.dep

5
vgui_support/cl.bat Normal file
View File

@ -0,0 +1,5 @@
set MSVCDir=Z:\path\to\msvc
set INCLUDE=%MSVCDir%\include
set LIB=%MSVCDir%\lib
set PATH=%MSVCDir%\bin;%PATH%
cl.exe %*

368
vgui_support/utlmemory.h Normal file
View File

@ -0,0 +1,368 @@
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// $Header: $
// $NoKeywords: $
//
// A growable memory class.
//=============================================================================
#ifndef UTLMEMORY_H
#define UTLMEMORY_H
#ifdef _WIN32
#pragma once
#endif
#include "port.h"
#include <string.h>
#ifdef NO_STL
template <class T>
void *operator new(size_t count, T *ptr) {
return ptr;
}
#elif defined _WIN32
#include <new.h>
#else
#include <new>
#endif
#include <stdlib.h>
#include <math.h>
//-----------------------------------------------------------------------------
// Methods to invoke the constructor, copy constructor, and destructor
//-----------------------------------------------------------------------------
template <class T>
inline void Construct( T* pMemory )
{
new( pMemory ) T;
}
template <class T>
inline void CopyConstruct( T* pMemory, T const& src )
{
new( pMemory ) T(src);
}
template <class T>
inline void Destruct( T* pMemory )
{
pMemory->~T();
#ifdef _DEBUG
memset( pMemory, 0xDD, sizeof(T) );
#endif
}
#pragma warning (disable:4100)
#pragma warning (disable:4514)
//-----------------------------------------------------------------------------
// The CUtlMemory class:
// A growable memory class which doubles in size by default.
//-----------------------------------------------------------------------------
template< class T >
class CUtlMemory
{
public:
// constructor, destructor
CUtlMemory( int nGrowSize = 0, int nInitSize = 0 );
CUtlMemory( T* pMemory, int numElements );
~CUtlMemory();
// element access
T& operator[]( int i );
T const& operator[]( int i ) const;
T& Element( int i );
T const& Element( int i ) const;
// Can we use this index?
bool IsIdxValid( int i ) const;
// Gets the base address (can change when adding elements!)
T* Base();
T const* Base() const;
// Attaches the buffer to external memory....
void SetExternalBuffer( T* pMemory, int numElements );
// Size
int NumAllocated() const;
int Count() const;
// Grows the memory, so that at least allocated + num elements are allocated
void Grow( int num = 1 );
// Makes sure we've got at least this much memory
void EnsureCapacity( int num );
// Memory deallocation
void Purge();
// is the memory externally allocated?
bool IsExternallyAllocated() const;
// Set the size by which the memory grows
void SetGrowSize( int size );
private:
enum
{
EXTERNAL_BUFFER_MARKER = -1
};
T* m_pMemory;
int m_nAllocationCount;
int m_nGrowSize;
};
//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
template< class T >
CUtlMemory<T>::CUtlMemory( int nGrowSize, int nInitAllocationCount ) : m_pMemory(0),
m_nAllocationCount( nInitAllocationCount ), m_nGrowSize( nGrowSize )
{
Assert( (nGrowSize >= 0) && (nGrowSize != EXTERNAL_BUFFER_MARKER) );
if (m_nAllocationCount)
{
m_pMemory = (T*)malloc( m_nAllocationCount * sizeof(T) );
}
}
template< class T >
CUtlMemory<T>::CUtlMemory( T* pMemory, int numElements ) : m_pMemory(pMemory),
m_nAllocationCount( numElements )
{
// Special marker indicating externally supplied memory
m_nGrowSize = EXTERNAL_BUFFER_MARKER;
}
template< class T >
CUtlMemory<T>::~CUtlMemory()
{
Purge();
}
//-----------------------------------------------------------------------------
// Attaches the buffer to external memory....
//-----------------------------------------------------------------------------
template< class T >
void CUtlMemory<T>::SetExternalBuffer( T* pMemory, int numElements )
{
// Blow away any existing allocated memory
Purge();
m_pMemory = pMemory;
m_nAllocationCount = numElements;
// Indicate that we don't own the memory
m_nGrowSize = EXTERNAL_BUFFER_MARKER;
}
//-----------------------------------------------------------------------------
// element access
//-----------------------------------------------------------------------------
template< class T >
inline T& CUtlMemory<T>::operator[]( int i )
{
Assert( IsIdxValid(i) );
return m_pMemory[i];
}
template< class T >
inline T const& CUtlMemory<T>::operator[]( int i ) const
{
Assert( IsIdxValid(i) );
return m_pMemory[i];
}
template< class T >
inline T& CUtlMemory<T>::Element( int i )
{
Assert( IsIdxValid(i) );
return m_pMemory[i];
}
template< class T >
inline T const& CUtlMemory<T>::Element( int i ) const
{
Assert( IsIdxValid(i) );
return m_pMemory[i];
}
//-----------------------------------------------------------------------------
// is the memory externally allocated?
//-----------------------------------------------------------------------------
template< class T >
bool CUtlMemory<T>::IsExternallyAllocated() const
{
return m_nGrowSize == EXTERNAL_BUFFER_MARKER;
}
template< class T >
void CUtlMemory<T>::SetGrowSize( int nSize )
{
Assert( (nSize >= 0) && (nSize != EXTERNAL_BUFFER_MARKER) );
m_nGrowSize = nSize;
}
//-----------------------------------------------------------------------------
// Gets the base address (can change when adding elements!)
//-----------------------------------------------------------------------------
template< class T >
inline T* CUtlMemory<T>::Base()
{
return m_pMemory;
}
template< class T >
inline T const* CUtlMemory<T>::Base() const
{
return m_pMemory;
}
//-----------------------------------------------------------------------------
// Size
//-----------------------------------------------------------------------------
template< class T >
inline int CUtlMemory<T>::NumAllocated() const
{
return m_nAllocationCount;
}
template< class T >
inline int CUtlMemory<T>::Count() const
{
return m_nAllocationCount;
}
//-----------------------------------------------------------------------------
// Is element index valid?
//-----------------------------------------------------------------------------
template< class T >
inline bool CUtlMemory<T>::IsIdxValid( int i ) const
{
return (i >= 0) && (i < m_nAllocationCount);
}
//-----------------------------------------------------------------------------
// Grows the memory
//-----------------------------------------------------------------------------
template< class T >
void CUtlMemory<T>::Grow( int num )
{
Assert( num > 0 );
if (IsExternallyAllocated())
{
// Can't grow a buffer whose memory was externally allocated
Assert(0);
return;
}
// Make sure we have at least numallocated + num allocations.
// Use the grow rules specified for this memory (in m_nGrowSize)
int nAllocationRequested = m_nAllocationCount + num;
while (m_nAllocationCount < nAllocationRequested)
{
if ( m_nAllocationCount != 0 )
{
if (m_nGrowSize)
{
m_nAllocationCount += m_nGrowSize;
}
else
{
m_nAllocationCount += m_nAllocationCount;
}
}
else
{
// Compute an allocation which is at least as big as a cache line...
m_nAllocationCount = (31 + sizeof(T)) / sizeof(T);
Assert(m_nAllocationCount != 0);
}
}
if (m_pMemory)
{
T* pTempMemory = ( T* )realloc( m_pMemory, m_nAllocationCount * sizeof( T ) );
if( !pTempMemory )
return;
m_pMemory = pTempMemory;
}
else
{
m_pMemory = (T*)malloc( m_nAllocationCount * sizeof(T) );
}
}
//-----------------------------------------------------------------------------
// Makes sure we've got at least this much memory
//-----------------------------------------------------------------------------
template< class T >
inline void CUtlMemory<T>::EnsureCapacity( int num )
{
if (m_nAllocationCount >= num)
return;
if (IsExternallyAllocated())
{
// Can't grow a buffer whose memory was externally allocated
Assert(0);
return;
}
m_nAllocationCount = num;
if (m_pMemory)
{
T* pTempMemory = ( T* )realloc( m_pMemory, m_nAllocationCount * sizeof( T ) );
if( !pTempMemory )
return;
m_pMemory = pTempMemory;
}
else
{
m_pMemory = (T*)malloc( m_nAllocationCount * sizeof(T) );
}
}
//-----------------------------------------------------------------------------
// Memory deallocation
//-----------------------------------------------------------------------------
template< class T >
void CUtlMemory<T>::Purge()
{
if (!IsExternallyAllocated())
{
if (m_pMemory)
{
free( (void*)m_pMemory );
m_pMemory = 0;
}
m_nAllocationCount = 0;
}
}
#endif//UTLMEMORY_H

1289
vgui_support/utlrbtree.h Normal file

File diff suppressed because it is too large Load Diff

605
vgui_support/utlvector.h Normal file
View File

@ -0,0 +1,605 @@
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// $Header: $
// $NoKeywords: $
//
// A growable array class that maintains a free list and keeps elements
// in the same location
//=============================================================================
#ifndef UTLVECTOR_H
#define UTLVECTOR_H
#ifdef _WIN32
#pragma once
#endif
#include "port.h"
#include <string.h>
#include "utlmemory.h"
//-----------------------------------------------------------------------------
// The CUtlVector class:
// A growable array class which doubles in size by default.
// It will always keep all elements consecutive in memory, and may move the
// elements around in memory (via a realloc) when elements are inserted or
// removed. Clients should therefore refer to the elements of the vector
// by index (they should *never* maintain pointers to elements in the vector).
//-----------------------------------------------------------------------------
template< class T >
class CUtlVector
{
public:
typedef T ElemType_t;
// constructor, destructor
CUtlVector( int growSize = 0, int initSize = 0 );
CUtlVector( T* pMemory, int numElements );
~CUtlVector();
// Copy the array.
CUtlVector<T>& operator=( const CUtlVector<T> &other );
// element access
T& operator[]( int i );
T const& operator[]( int i ) const;
T& Element( int i );
T const& Element( int i ) const;
// Gets the base address (can change when adding elements!)
T* Base();
T const* Base() const;
// Returns the number of elements in the vector
// SIZE IS DEPRECATED!
int Count() const;
int Size() const; // don't use me!
// Is element index valid?
bool IsValidIndex( int i ) const;
static int InvalidIndex( void );
// Adds an element, uses default constructor
int AddToHead();
int AddToTail();
int InsertBefore( int elem );
int InsertAfter( int elem );
// Adds an element, uses copy constructor
int AddToHead( T const& src );
int AddToTail( T const& src );
int InsertBefore( int elem, T const& src );
int InsertAfter( int elem, T const& src );
// Adds multiple elements, uses default constructor
int AddMultipleToHead( int num );
int AddMultipleToTail( int num, const T *pToCopy=NULL );
int InsertMultipleBefore( int elem, int num, const T *pToCopy=NULL ); // If pToCopy is set, then it's an array of length 'num' and
int InsertMultipleAfter( int elem, int num );
// Calls RemoveAll() then AddMultipleToTail.
void SetSize( int size );
void SetCount( int count );
// Calls SetSize and copies each element.
void CopyArray( T const *pArray, int size );
// Add the specified array to the tail.
int AddVectorToTail( CUtlVector<T> const &src );
// Finds an element (element needs operator== defined)
int Find( T const& src ) const;
bool HasElement( T const& src );
// Makes sure we have enough memory allocated to store a requested # of elements
void EnsureCapacity( int num );
// Makes sure we have at least this many elements
void EnsureCount( int num );
// Element removal
void FastRemove( int elem ); // doesn't preserve order
void Remove( int elem ); // preserves order, shifts elements
void FindAndRemove( T const& src ); // removes first occurrence of src, preserves order, shifts elements
void RemoveMultiple( int elem, int num ); // preserves order, shifts elements
void RemoveAll(); // doesn't deallocate memory
// Memory deallocation
void Purge();
// Purges the list and calls delete on each element in it.
void PurgeAndDeleteElements();
// Set the size by which it grows when it needs to allocate more memory.
void SetGrowSize( int size );
protected:
// Can't copy this unless we explicitly do it!
CUtlVector( CUtlVector const& vec ) { Assert(0); }
// Grows the vector
void GrowVector( int num = 1 );
// Shifts elements....
void ShiftElementsRight( int elem, int num = 1 );
void ShiftElementsLeft( int elem, int num = 1 );
// For easier access to the elements through the debugger
void ResetDbgInfo();
CUtlMemory<T> m_Memory;
int m_Size;
// For easier access to the elements through the debugger
// it's in release builds so this can be used in libraries correctly
T *m_pElements;
};
//-----------------------------------------------------------------------------
// For easier access to the elements through the debugger
//-----------------------------------------------------------------------------
template< class T >
inline void CUtlVector<T>::ResetDbgInfo()
{
m_pElements = m_Memory.Base();
}
//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
template< class T >
inline CUtlVector<T>::CUtlVector( int growSize, int initSize ) :
m_Memory(growSize, initSize), m_Size(0)
{
ResetDbgInfo();
}
template< class T >
inline CUtlVector<T>::CUtlVector( T* pMemory, int numElements ) :
m_Memory(pMemory, numElements), m_Size(0)
{
ResetDbgInfo();
}
template< class T >
inline CUtlVector<T>::~CUtlVector()
{
Purge();
}
template<class T>
inline CUtlVector<T>& CUtlVector<T>::operator=( const CUtlVector<T> &other )
{
CopyArray( other.Base(), other.Count() );
return *this;
}
//-----------------------------------------------------------------------------
// element access
//-----------------------------------------------------------------------------
template< class T >
inline T& CUtlVector<T>::operator[]( int i )
{
Assert( IsValidIndex(i) );
return m_Memory[i];
}
template< class T >
inline T const& CUtlVector<T>::operator[]( int i ) const
{
Assert( IsValidIndex(i) );
return m_Memory[i];
}
template< class T >
inline T& CUtlVector<T>::Element( int i )
{
Assert( IsValidIndex(i) );
return m_Memory[i];
}
template< class T >
inline T const& CUtlVector<T>::Element( int i ) const
{
Assert( IsValidIndex(i) );
return m_Memory[i];
}
//-----------------------------------------------------------------------------
// Gets the base address (can change when adding elements!)
//-----------------------------------------------------------------------------
template< class T >
inline T* CUtlVector<T>::Base()
{
return m_Memory.Base();
}
template< class T >
inline T const* CUtlVector<T>::Base() const
{
return m_Memory.Base();
}
//-----------------------------------------------------------------------------
// Count
//-----------------------------------------------------------------------------
template< class T >
inline int CUtlVector<T>::Size() const
{
return m_Size;
}
template< class T >
inline int CUtlVector<T>::Count() const
{
return m_Size;
}
//-----------------------------------------------------------------------------
// Is element index valid?
//-----------------------------------------------------------------------------
template< class T >
inline bool CUtlVector<T>::IsValidIndex( int i ) const
{
return (i >= 0) && (i < m_Size);
}
//-----------------------------------------------------------------------------
// Returns in invalid index
//-----------------------------------------------------------------------------
template< class T >
inline int CUtlVector<T>::InvalidIndex( void )
{
return -1;
}
//-----------------------------------------------------------------------------
// Grows the vector
//-----------------------------------------------------------------------------
template< class T >
void CUtlVector<T>::GrowVector( int num )
{
if (m_Size + num - 1 >= m_Memory.NumAllocated())
{
m_Memory.Grow( m_Size + num - m_Memory.NumAllocated() );
}
m_Size += num;
ResetDbgInfo();
}
//-----------------------------------------------------------------------------
// Makes sure we have enough memory allocated to store a requested # of elements
//-----------------------------------------------------------------------------
template< class T >
void CUtlVector<T>::EnsureCapacity( int num )
{
m_Memory.EnsureCapacity(num);
ResetDbgInfo();
}
//-----------------------------------------------------------------------------
// Makes sure we have at least this many elements
//-----------------------------------------------------------------------------
template< class T >
void CUtlVector<T>::EnsureCount( int num )
{
if (Count() < num)
AddMultipleToTail( num - Count() );
}
//-----------------------------------------------------------------------------
// Shifts elements
//-----------------------------------------------------------------------------
template< class T >
void CUtlVector<T>::ShiftElementsRight( int elem, int num )
{
Assert( IsValidIndex(elem) || ( m_Size == 0 ) || ( num == 0 ));
int numToMove = m_Size - elem - num;
if ((numToMove > 0) && (num > 0))
memmove( &Element(elem+num), &Element(elem), numToMove * sizeof(T) );
}
template< class T >
void CUtlVector<T>::ShiftElementsLeft( int elem, int num )
{
Assert( IsValidIndex(elem) || ( m_Size == 0 ) || ( num == 0 ));
int numToMove = m_Size - elem - num;
if ((numToMove > 0) && (num > 0))
{
memmove( &Element(elem), &Element(elem+num), numToMove * sizeof(T) );
#ifdef _DEBUG
memset( &Element(m_Size-num), 0xDD, num * sizeof(T) );
#endif
}
}
//-----------------------------------------------------------------------------
// Adds an element, uses default constructor
//-----------------------------------------------------------------------------
template< class T >
inline int CUtlVector<T>::AddToHead()
{
return InsertBefore(0);
}
template< class T >
inline int CUtlVector<T>::AddToTail()
{
return InsertBefore( m_Size );
}
template< class T >
inline int CUtlVector<T>::InsertAfter( int elem )
{
return InsertBefore( elem + 1 );
}
template< class T >
int CUtlVector<T>::InsertBefore( int elem )
{
// Can insert at the end
Assert( (elem == Count()) || IsValidIndex(elem) );
GrowVector();
ShiftElementsRight(elem);
Construct( &Element(elem) );
return elem;
}
//-----------------------------------------------------------------------------
// Adds an element, uses copy constructor
//-----------------------------------------------------------------------------
template< class T >
inline int CUtlVector<T>::AddToHead( T const& src )
{
return InsertBefore( 0, src );
}
template< class T >
inline int CUtlVector<T>::AddToTail( T const& src )
{
return InsertBefore( m_Size, src );
}
template< class T >
inline int CUtlVector<T>::InsertAfter( int elem, T const& src )
{
return InsertBefore( elem + 1, src );
}
template< class T >
int CUtlVector<T>::InsertBefore( int elem, T const& src )
{
// Can insert at the end
Assert( (elem == Count()) || IsValidIndex(elem) );
GrowVector();
ShiftElementsRight(elem);
CopyConstruct( &Element(elem), src );
return elem;
}
//-----------------------------------------------------------------------------
// Adds multiple elements, uses default constructor
//-----------------------------------------------------------------------------
template< class T >
inline int CUtlVector<T>::AddMultipleToHead( int num )
{
return InsertMultipleBefore( 0, num );
}
template< class T >
inline int CUtlVector<T>::AddMultipleToTail( int num, const T *pToCopy )
{
return InsertMultipleBefore( m_Size, num, pToCopy );
}
template< class T >
int CUtlVector<T>::InsertMultipleAfter( int elem, int num )
{
return InsertMultipleBefore( elem + 1, num );
}
template< class T >
void CUtlVector<T>::SetCount( int count )
{
RemoveAll();
AddMultipleToTail( count );
}
template< class T >
inline void CUtlVector<T>::SetSize( int size )
{
SetCount( size );
}
template< class T >
void CUtlVector<T>::CopyArray( T const *pArray, int size )
{
SetSize( size );
for( int i=0; i < size; i++ )
(*this)[i] = pArray[i];
}
template< class T >
int CUtlVector<T>::AddVectorToTail( CUtlVector const &src )
{
int base = Count();
// Make space.
AddMultipleToTail( src.Count() );
// Copy the elements.
for ( int i=0; i < src.Count(); i++ )
(*this)[base + i] = src[i];
return base;
}
template< class T >
inline int CUtlVector<T>::InsertMultipleBefore( int elem, int num, const T *pToInsert )
{
if( num == 0 )
return elem;
// Can insert at the end
Assert( (elem == Count()) || IsValidIndex(elem) );
GrowVector(num);
ShiftElementsRight(elem, num);
// Invoke default constructors
for (int i = 0; i < num; ++i)
Construct( &Element(elem+i) );
// Copy stuff in?
if ( pToInsert )
{
for ( int i=0; i < num; i++ )
{
Element( elem+i ) = pToInsert[i];
}
}
return elem;
}
//-----------------------------------------------------------------------------
// Finds an element (element needs operator== defined)
//-----------------------------------------------------------------------------
template< class T >
int CUtlVector<T>::Find( T const& src ) const
{
for ( int i = 0; i < Count(); ++i )
{
if (Element(i) == src)
return i;
}
return -1;
}
template< class T >
bool CUtlVector<T>::HasElement( T const& src )
{
return ( Find(src) >= 0 );
}
//-----------------------------------------------------------------------------
// Element removal
//-----------------------------------------------------------------------------
template< class T >
void CUtlVector<T>::FastRemove( int elem )
{
Assert( IsValidIndex(elem) );
Destruct( &Element(elem) );
if (m_Size > 0)
{
memcpy( &Element(elem), &Element(m_Size-1), sizeof(T) );
--m_Size;
}
}
template< class T >
void CUtlVector<T>::Remove( int elem )
{
Destruct( &Element(elem) );
ShiftElementsLeft(elem);
--m_Size;
}
template< class T >
void CUtlVector<T>::FindAndRemove( T const& src )
{
int elem = Find( src );
if ( elem != -1 )
{
Remove( elem );
}
}
template< class T >
void CUtlVector<T>::RemoveMultiple( int elem, int num )
{
Assert( IsValidIndex(elem) );
Assert( elem + num <= Count() );
for (int i = elem + num; --i >= elem; )
Destruct(&Element(i));
ShiftElementsLeft(elem, num);
m_Size -= num;
}
template< class T >
void CUtlVector<T>::RemoveAll()
{
for (int i = m_Size; --i >= 0; )
Destruct(&Element(i));
m_Size = 0;
}
//-----------------------------------------------------------------------------
// Memory deallocation
//-----------------------------------------------------------------------------
template< class T >
void CUtlVector<T>::Purge()
{
RemoveAll();
m_Memory.Purge( );
ResetDbgInfo();
}
template<class T>
inline void CUtlVector<T>::PurgeAndDeleteElements()
{
for( int i=0; i < m_Size; i++ )
delete Element(i);
Purge();
}
template< class T >
void CUtlVector<T>::SetGrowSize( int size )
{
m_Memory.SetGrowSize( size );
}
#endif//UTLVECTOR_H

View File

@ -11,10 +11,19 @@ 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 "common.h"
#include "vgui_draw.h"
#include "vgui_main.h"
#include "wrect.h"
//-----------------------------------------------------------------------------
@ -22,7 +31,7 @@ GNU General Public License for more details.
//-----------------------------------------------------------------------------
static wrect_t g_ScissorRect;
static qboolean g_bScissor = false;
namespace vgui_support {
//-----------------------------------------------------------------------------
// Enable/disable scissoring...
//-----------------------------------------------------------------------------
@ -95,11 +104,15 @@ qboolean ClipRect( const vpoint_t &inUL, const vpoint_t &inLR, vpoint_t *pOutUL,
return false;
}
pOutUL->coord[0] = InterpTCoord(pOutUL->point[0], inUL.point[0], inLR.point[0], inUL.coord[0], inLR.coord[0] );
pOutLR->coord[0] = InterpTCoord(pOutLR->point[0], inUL.point[0], inLR.point[0], inUL.coord[0], inLR.coord[0] );
pOutUL->coord[0] = InterpTCoord(pOutUL->point[0],
inUL.point[0], inLR.point[0], inUL.coord[0], inLR.coord[0] );
pOutLR->coord[0] = InterpTCoord(pOutLR->point[0],
inUL.point[0], inLR.point[0], inUL.coord[0], inLR.coord[0] );
pOutUL->coord[1] = InterpTCoord(pOutUL->point[1], inUL.point[1], inLR.point[1], inUL.coord[1], inLR.coord[1] );
pOutLR->coord[1] = InterpTCoord(pOutLR->point[1], inUL.point[1], inLR.point[1], inUL.coord[1], inLR.coord[1] );
pOutUL->coord[1] = InterpTCoord(pOutUL->point[1],
inUL.point[1], inLR.point[1], inUL.coord[1], inLR.coord[1] );
pOutLR->coord[1] = InterpTCoord(pOutLR->point[1],
inUL.point[1], inLR.point[1], inUL.coord[1], inLR.coord[1] );
}
else
{
@ -107,4 +120,5 @@ qboolean ClipRect( const vpoint_t &inUL, const vpoint_t &inLR, vpoint_t *pOutUL,
*pOutLR = inLR;
}
return true;
}
}

185
vgui_support/vgui_font.cpp Normal file
View File

@ -0,0 +1,185 @@
/*
vgui_font.cpp - fonts management
Copyright (C) 2011 Uncle Mike
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 "vgui_main.h"
int FontCache::s_pFontPageSize[FONT_PAGE_SIZE_COUNT] = { 16, 32, 64, 128 };
FontCache::FontCache() : m_CharCache( 0, 256, CacheEntryLessFunc )
{
CacheEntry_t listHead = { 0, 0 };
m_LRUListHeadIndex = m_CharCache.Insert( listHead );
m_CharCache[m_LRUListHeadIndex].nextEntry = m_LRUListHeadIndex;
m_CharCache[m_LRUListHeadIndex].prevEntry = m_LRUListHeadIndex;
for( int i = 0; i < FONT_PAGE_SIZE_COUNT; i++ )
{
m_pCurrPage[i] = -1;
}
}
bool FontCache::CacheEntryLessFunc( CacheEntry_t const &lhs, CacheEntry_t const &rhs )
{
if( lhs.font < rhs.font )
return true;
else if( lhs.font > rhs.font )
return false;
return ( lhs.ch < rhs.ch );
}
bool FontCache::GetTextureForChar( Font *font, char ch, int *textureID, float **texCoords )
{
static CacheEntry_t cacheitem;
cacheitem.font = font;
cacheitem.ch = ch;
Assert( texCoords != NULL );
*texCoords = cacheitem.texCoords;
HCacheEntry cacheHandle = m_CharCache.Find( cacheitem );
if( cacheHandle != 65535 && m_CharCache.IsValidIndex( cacheHandle ))
{
// we have an entry already, return that
int page = m_CharCache[cacheHandle].page;
*textureID = m_PageList[page].textureID;
//else return false;
*texCoords = m_CharCache[cacheHandle].texCoords;
return true;
}
// get the char details
int fontTall = font->getTall();
int a, b, c;
font->getCharABCwide( (byte)ch, a, b, c );
int fontWide = b;
// get a texture to render into
int page, drawX, drawY, twide, ttall;
if( !AllocatePageForChar( fontWide, fontTall, page, drawX, drawY, twide, ttall ))
return false;
// create a buffer and render the character into it
int nByteCount = s_pFontPageSize[FONT_PAGE_SIZE_COUNT-1] * s_pFontPageSize[FONT_PAGE_SIZE_COUNT-1] * 4;
byte * rgba = (byte *)g_api->EngineMalloc(nByteCount);//(byte *)Z_Malloc( nByteCount );
font->getCharRGBA( (byte)ch, 0, 0, fontWide, fontTall, rgba );
// upload the new sub texture
g_api->BindTexture( m_PageList[page].textureID );
g_api->UploadTextureBlock( m_PageList[page].textureID, drawX, drawY, rgba, fontWide, fontTall );
// set the cache info
cacheitem.page = page;
cacheitem.texCoords[0] = (float)((double)drawX / ((double)twide));
cacheitem.texCoords[1] = (float)((double)drawY / ((double)ttall));
cacheitem.texCoords[2] = (float)((double)(drawX + fontWide) / (double)twide);
cacheitem.texCoords[3] = (float)((double)(drawY + fontTall) / (double)ttall);
m_CharCache.Insert( cacheitem );
// return the data
*textureID = m_PageList[page].textureID;
// memcpy( texCoords, cacheitem.texCoords, sizeof( float ) * 4 );
return true;
}
int FontCache::ComputePageType( int charTall ) const
{
for( int i = 0; i < FONT_PAGE_SIZE_COUNT; i++ )
{
if( charTall < s_pFontPageSize[i] )
return i;
}
return -1;
}
bool FontCache::AllocatePageForChar( int charWide, int charTall, int &pageIndex, int &drawX, int &drawY, int &twide, int &ttall )
{
// see if there is room in the last page for this character
int nPageType = ComputePageType( charTall );
if( nPageType < 0 )
return false;
pageIndex = m_pCurrPage[nPageType];
int nNextX = 0;
bool bNeedsNewPage = true;
if( pageIndex > -1 )
{
Page_t &page = m_PageList[pageIndex];
nNextX = page.nextX + charWide;
// make sure we have room on the current line of the texture page
if( nNextX > page.wide )
{
// move down a line
page.nextX = 0;
nNextX = charWide;
page.nextY += page.fontHeight + 1;
}
bNeedsNewPage = (( page.nextY + page.fontHeight + 1 ) > page.tall );
}
if( bNeedsNewPage )
{
// allocate a new page
pageIndex = m_PageList.AddToTail();
Page_t &newPage = m_PageList[pageIndex];
m_pCurrPage[nPageType] = pageIndex;
newPage.textureID = g_api->GenerateTexture();
newPage.fontHeight = s_pFontPageSize[nPageType];
newPage.wide = 256;
newPage.tall = 256;
newPage.nextX = 0;
newPage.nextY = 0;
nNextX = charWide;
// create empty texture
g_api->CreateTexture( newPage.textureID, 256, 256 );
}
// output the position
Page_t &page = m_PageList[pageIndex];
drawX = page.nextX;
drawY = page.nextY;
twide = page.wide;
ttall = page.tall;
// update the next position to draw in
page.nextX = nNextX + 1;
return true;
}

View File

@ -0,0 +1,86 @@
/*
vgui_input.cpp - handle kb & mouse
Copyright (C) 2011 Uncle Mike
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.
*/
#define OEMRESOURCE // for OCR_* cursor junk
#include "vgui_main.h"
namespace vgui_support {
void VGUI_Key(VGUI_KeyAction action, VGUI_KeyCode code)
{
App *pApp = App::getInstance();
if(!surface)
return;
switch( action )
{
case KA_PRESSED:
pApp->internalKeyPressed( (KeyCode) code, surface );
break;
case KA_RELEASED:
pApp->internalKeyReleased( (KeyCode) code, surface );
break;
case KA_TYPED:
pApp->internalKeyTyped( (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)
{
App *pApp = App::getInstance();
if(!surface)
return;
switch( action )
{
case MA_PRESSED:
pApp->internalMousePressed( (MouseCode) code, surface );
break;
case MA_RELEASED:
pApp->internalMouseReleased( (MouseCode) code, surface );
break;
case MA_DOUBLE:
pApp->internalMouseDoublePressed( (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)
{
App *pApp = App::getInstance();
//fprintf(stdout, "vgui_support: VGUI mouse move %d %d %p\n", x, y, surface);
//fflush(stdout);
if(!surface)
return;
pApp->internalCursorMoved( x, y, surface );
}
}

132
vgui_support/vgui_int.cpp Normal file
View File

@ -0,0 +1,132 @@
/*
vgui_int.c - vgui dll interaction
Copyright (C) 2011 Uncle Mike
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 "vgui_main.h"
namespace vgui_support {
vguiapi_t *g_api;
FontCache *g_FontCache = 0;
Panel *rootpanel = NULL;
CEngineSurface *surface = NULL;
CEngineApp staticApp;
void VGui_Startup( int width, int height )
{
if( !g_FontCache )
{
g_FontCache = new FontCache();
}
if( rootpanel )
{
rootpanel->setSize( width, height );
return;
}
rootpanel = new Panel;
rootpanel->setSize( width, height );
rootpanel->setPaintBorderEnabled( false );
rootpanel->setPaintBackgroundEnabled( false );
rootpanel->setVisible( true );
rootpanel->setCursor( new Cursor( Cursor::dc_none ));
staticApp.start();
staticApp.setMinimumTickMillisInterval( 0 );
surface = new CEngineSurface( rootpanel );
rootpanel->setSurfaceBaseTraverse( surface );
//ASSERT( rootpanel->getApp() != NULL );
//ASSERT( rootpanel->getSurfaceBase() != NULL );
g_api->DrawInit ();
}
void VGui_Shutdown( void )
{
staticApp.stop();
delete rootpanel;
delete surface;
rootpanel = NULL;
surface = NULL;
}
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();
rootpanel->getSize(w, h);
EnableScissor( true );
staticApp.externalTick ();
pVPanel->setBounds( 0, 0, w, h );
pVPanel->repaint();
// paint everything
pVPanel->paintTraverse();
EnableScissor( false );
}
void *VGui_GetPanel( void )
{
return (void *)rootpanel;
}
}
#ifdef INTERNAL_VGUI_SUPPORT
#define InitAPI InitVGUISupportAPI
#endif
#ifdef _WIN32
extern "C" void _declspec( dllexport ) InitAPI(vguiapi_t * api)
#else
extern "C" void InitAPI(vguiapi_t * api)
#endif
{
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;
}

225
vgui_support/vgui_main.h Normal file
View File

@ -0,0 +1,225 @@
/*
vgui_main.h - vgui main header
Copyright (C) 2011 Uncle Mike
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 VGUI_MAIN_H
#define VGUI_MAIN_H
#define Assert(x)
#ifdef _WIN32
#include <windows.h>
#else
#include <string.h>
#endif
#include "vgui_api.h"
#include "utlvector.h"
#include "utlrbtree.h"
#include<VGUI.h>
#include<VGUI_App.h>
#include<VGUI_Font.h>
#include<VGUI_Panel.h>
#include<VGUI_Cursor.h>
#include<VGUI_SurfaceBase.h>
#include<VGUI_InputSignal.h>
#include<VGUI_MouseCode.h>
#include<VGUI_KeyCode.h>
namespace vgui_support
{
extern vguiapi_t *g_api;
using namespace vgui;
class FontCache
{
public:
FontCache();
~FontCache() { }
// returns a texture ID and a pointer to an array of 4 texture coords for the given character & font
// uploads more texture if necessary
bool GetTextureForChar( Font *font, char ch, int *textureID, float **texCoords );
private:
// NOTE: If you change this, change s_pFontPageSize
enum
{
FONT_PAGE_SIZE_16,
FONT_PAGE_SIZE_32,
FONT_PAGE_SIZE_64,
FONT_PAGE_SIZE_128,
FONT_PAGE_SIZE_COUNT
};
// a single character in the cache
typedef unsigned short HCacheEntry;
struct CacheEntry_t
{
Font *font;
char ch;
byte page;
float texCoords[4];
HCacheEntry nextEntry; // doubly-linked list for use in the LRU
HCacheEntry prevEntry;
};
// a single texture page
struct Page_t
{
short textureID;
short fontHeight;
short wide, tall; // total size of the page
short nextX, nextY; // position to draw any new character positions
};
// allocates a new page for a given character
bool AllocatePageForChar( int charWide, int charTall, int &pageIndex, int &drawX, int &drawY, int &twide, int &ttall );
// Computes the page size given a character height
int ComputePageType( int charTall ) const;
static bool CacheEntryLessFunc( const CacheEntry_t &lhs, const CacheEntry_t &rhs );
// cache
typedef CUtlVector<Page_t> FontPageList_t;
CUtlRBTree<CacheEntry_t, HCacheEntry> m_CharCache;
FontPageList_t m_PageList;
int m_pCurrPage[FONT_PAGE_SIZE_COUNT];
HCacheEntry m_LRUListHeadIndex;
static int s_pFontPageSize[FONT_PAGE_SIZE_COUNT];
};
class CEngineSurface : public SurfaceBase
{
private:
struct paintState_t
{
Panel *m_pPanel;
int iTranslateX;
int iTranslateY;
int iScissorLeft;
int iScissorRight;
int iScissorTop;
int iScissorBottom;
};
// point translation for current panel
int _translateX;
int _translateY;
// the size of the window to draw into
int _surfaceExtents[4];
CUtlVector <paintState_t> _paintStack;
void SetupPaintState( const paintState_t &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);
}
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:
Font* _hCurrentFont;
Cursor* _hCurrentCursor;
int _drawTextPos[2];
int _drawColor[4];
int _drawTextColor[4];
friend class App;
friend class Panel;
};
// 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
};
//
// vgui_input.cpp
//
void VGUI_InitCursors( void );
void VGUI_CursorSelect( Cursor *cursor );
void VGUI_ActivateCurrentCursor( void );
void *VGui_GetPanel( void );
void VGui_RunFrame( 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);
//
// vgui_clip.cpp
//
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 FontCache *g_FontCache;
extern CEngineSurface *surface;
extern Panel *root;
}
using namespace vgui_support;
#endif//VGUI_MAIN_H

339
vgui_support/vgui_surf.cpp Normal file
View File

@ -0,0 +1,339 @@
/*
vgui_surf.cpp - main vgui layer
Copyright (C) 2011 Uncle Mike
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 <ctype.h>
#include "vgui_main.h"
#define ColorIndex( c )((( c ) - '0' ) & 7 )
CEngineSurface :: CEngineSurface( Panel *embeddedPanel ):SurfaceBase( embeddedPanel )
{
_embeddedPanel = embeddedPanel;
_drawColor[0] = _drawColor[1] = _drawColor[2] = _drawColor[3] = 255;
_drawTextColor[0] = _drawTextColor[1] = _drawTextColor[2] = _drawTextColor[3] = 255;
_surfaceExtents[0] = _surfaceExtents[1] = 0;
//_surfaceExtents[2] = menu.globals->scrWidth;
//_surfaceExtents[3] = menu.globals->scrHeight;
embeddedPanel->getSize(_surfaceExtents[2], _surfaceExtents[3]);
_drawTextPos[0] = _drawTextPos[1] = 0;
_hCurrentFont = null;
_hCurrentCursor = null;
_translateX = _translateY = 0;
}
CEngineSurface :: ~CEngineSurface( void )
{
g_api->DrawShutdown ();
}
Panel *CEngineSurface :: getEmbeddedPanel( void )
{
return _embeddedPanel;
}
bool CEngineSurface :: hasFocus( void )
{
// What differs when window does not has focus?
//return host.state != HOST_NOFOCUS;
return true;
}
void CEngineSurface :: setCursor( Cursor *cursor )
{
_currentCursor = cursor;
g_api->CursorSelect( (VGUI_DefaultCursor)cursor->getDefaultCursor() );
}
void CEngineSurface :: SetupPaintState( const paintState_t &paintState )
{
_translateX = paintState.iTranslateX;
_translateY = paintState.iTranslateY;
SetScissorRect( paintState.iScissorLeft, paintState.iScissorTop,
paintState.iScissorRight, paintState.iScissorBottom );
}
void CEngineSurface :: InitVertex( vpoint_t &vertex, int x, int y, float u, float v )
{
vertex.point[0] = x + _translateX;
vertex.point[1] = y + _translateY;
vertex.coord[0] = u;
vertex.coord[1] = v;
}
int CEngineSurface :: createNewTextureID( void )
{
return g_api->GenerateTexture();
}
void CEngineSurface :: drawSetColor( int r, int g, int b, int a )
{
_drawColor[0] = r;
_drawColor[1] = g;
_drawColor[2] = b;
_drawColor[3] = a;
}
void CEngineSurface :: drawSetTextColor( int r, int g, int b, int a )
{
_drawTextColor[0] = r;
_drawTextColor[1] = g;
_drawTextColor[2] = b;
_drawTextColor[3] = a;
}
void CEngineSurface :: drawFilledRect( int x0, int y0, int x1, int y1 )
{
vpoint_t rect[2];
vpoint_t clippedRect[2];
if( _drawColor[3] >= 255 ) return;
InitVertex( rect[0], x0, y0, 0, 0 );
InitVertex( rect[1], x1, y1, 0, 0 );
// fully clipped?
if( !ClipRect( rect[0], rect[1], &clippedRect[0], &clippedRect[1] ))
return;
g_api->SetupDrawingRect( _drawColor );
g_api->EnableTexture( false );
g_api->DrawQuad( &clippedRect[0], &clippedRect[1] );
g_api->EnableTexture( true );
}
void CEngineSurface :: drawOutlinedRect( int x0, int y0, int x1, int y1 )
{
if( _drawColor[3] >= 255 ) return;
drawFilledRect( x0, y0, x1, y0 + 1 ); // top
drawFilledRect( x0, y1 - 1, x1, y1 ); // bottom
drawFilledRect( x0, y0 + 1, x0 + 1, y1 - 1 ); // left
drawFilledRect( x1 - 1, y0 + 1, x1, y1 - 1 ); // right
}
void CEngineSurface :: drawSetTextFont( Font *font )
{
_hCurrentFont = font;
}
void CEngineSurface :: drawSetTextPos( int x, int y )
{
_drawTextPos[0] = x;
_drawTextPos[1] = y;
}
void CEngineSurface :: drawPrintText( const char* text, int textLen )
{
//return;
static bool hasColor = 0;
static int numColor = 7;
if( !text || !_hCurrentFont || _drawTextColor[3] >= 255 )
return;
int x = _drawTextPos[0] + _translateX;
int y = _drawTextPos[1] + _translateY;
int iTall = _hCurrentFont->getTall();
int j, iTotalWidth = 0;
int curTextColor[4];
// 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);
}
else
{
for( j = 0; j < 3; j++ ) // revert default color
curTextColor[j] = _drawTextColor[j];
}
curTextColor[3] = _drawTextColor[3]; // copy alpha
if( textLen == 1 )
{
if( *text == '^' )
{
hasColor = true;
return; // skip '^'
}
else if( hasColor && isdigit( *text ))
{
numColor = ColorIndex( *text );
hasColor = false; // handled
return; // skip colornum
}
else hasColor = false;
}
for( int i = 0; i < textLen; i++ )
{
char ch = g_api->ProcessUtfChar( (unsigned char)text[i] );
if( !ch )
{
continue;
}
int abcA,abcB,abcC;
_hCurrentFont->getCharABCwide( ch, abcA, abcB, abcC );
iTotalWidth += abcA;
int iWide = abcB;
//if( !iswspace( ch ))
{
// get the character texture from the cache
int iTexId = 0;
float *texCoords = NULL;
if( !g_FontCache->GetTextureForChar( _hCurrentFont, ch, &iTexId, &texCoords ))
{
continue;
}
Assert( texCoords != NULL );
vpoint_t ul, lr;
ul.point[0] = x + iTotalWidth;
ul.point[1] = y;
lr.point[0] = ul.point[0] + iWide;
lr.point[1] = ul.point[1] + iTall;
// gets at the texture coords for this character in its texture page
ul.coord[0] = texCoords[0];
ul.coord[1] = texCoords[1];
lr.coord[0] = texCoords[2];
lr.coord[1] = texCoords[3];
vpoint_t clippedRect[2];
if( !ClipRect( ul, lr, &clippedRect[0], &clippedRect[1] ))
continue;
drawSetTexture( iTexId );
g_api->SetupDrawingText( curTextColor );
g_api->DrawQuad( &clippedRect[0], &clippedRect[1] ); // draw the letter
}
iTotalWidth += iWide + abcC;
}
_drawTextPos[0] += iTotalWidth;
}
void CEngineSurface :: drawSetTextureRGBA( int id, const char* rgba, int wide, int tall )
{
g_api->UploadTexture( id, rgba, wide, tall );
}
void CEngineSurface :: drawSetTexture( int id )
{
g_api->BindTexture( id );
}
void CEngineSurface :: drawTexturedRect( int x0, int y0, int x1, int y1 )
{
vpoint_t rect[2];
vpoint_t clippedRect[2];
InitVertex( rect[0], x0, y0, 0, 0 );
InitVertex( rect[1], x1, y1, 1, 1 );
// fully clipped?
if( !ClipRect( rect[0], rect[1], &clippedRect[0], &clippedRect[1] ))
return;
g_api->SetupDrawingImage( _drawColor );
g_api->DrawQuad( &clippedRect[0], &clippedRect[1] );
}
void CEngineSurface :: pushMakeCurrent( Panel* panel, bool useInsets )
{
int inSets[4] = { 0, 0, 0, 0 };
int absExtents[4];
int clipRect[4];
if( useInsets )
{
panel->getInset( inSets[0], inSets[1], inSets[2], inSets[3] );
}
panel->getAbsExtents( absExtents[0], absExtents[1], absExtents[2], absExtents[3] );
panel->getClipRect( clipRect[0], clipRect[1], clipRect[2], clipRect[3] );
int i = _paintStack.AddToTail();
paintState_t &paintState = _paintStack[i];
paintState.m_pPanel = panel;
// determine corrected top left origin
paintState.iTranslateX = inSets[0] + absExtents[0] - _surfaceExtents[0];
paintState.iTranslateY = inSets[1] + absExtents[1] - _surfaceExtents[1];
// setup clipping rectangle for scissoring
paintState.iScissorLeft = clipRect[0] - _surfaceExtents[0];
paintState.iScissorTop = clipRect[1] - _surfaceExtents[1];
paintState.iScissorRight = clipRect[2] - _surfaceExtents[0];
paintState.iScissorBottom = clipRect[3] - _surfaceExtents[1];
SetupPaintState( paintState );
}
void CEngineSurface :: popMakeCurrent( Panel *panel )
{
int top = _paintStack.Count() - 1;
// more pops that pushes?
Assert( top >= 0 );
// didn't pop in reverse order of push?
Assert( _paintStack[top].m_pPanel == panel );
_paintStack.Remove( top );
if( top > 0 ) SetupPaintState( _paintStack[top-1] );
}
bool CEngineSurface :: setFullscreenMode( int wide, int tall, int bpp )
{
// NOTE: Xash3D always working in 32-bit mode
// Skip it now. VGUI cannot change video modes
/*if( R_DescribeVIDMode( wide, tall ))
{
Cvar_SetFloat( "fullscreen", 1.0f );
return true;
}*/
return false;
}
void CEngineSurface :: setWindowedMode( void )
{
// Skip it now. VGUI cannot change video modes
/*
Cvar_SetFloat( "fullscreen", 0.0f );
*/
}