Alibek Omarov
7 years ago
27 changed files with 4275 additions and 1282 deletions
@ -1,290 +0,0 @@
@@ -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; |
||||
} |
@ -1,129 +0,0 @@
@@ -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; |
||||
} |
@ -1,117 +0,0 @@
@@ -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
|
@ -1,465 +0,0 @@
@@ -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] ); |
||||
} |
@ -0,0 +1,215 @@
@@ -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
|
@ -0,0 +1,23 @@
@@ -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) |
@ -0,0 +1,89 @@
@@ -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() |
@ -0,0 +1,29 @@
@@ -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 |
@ -0,0 +1,5 @@
@@ -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 %* |
@ -0,0 +1,368 @@
@@ -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
|
@ -0,0 +1,605 @@
@@ -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
|
@ -0,0 +1,185 @@
@@ -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; |
||||
} |
@ -0,0 +1,86 @@
@@ -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 ); |
||||
} |
||||
} |
@ -0,0 +1,132 @@
@@ -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; |
||||
} |
@ -0,0 +1,225 @@
@@ -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
|
@ -0,0 +1,339 @@
@@ -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 ); |
||||
*/ |
||||
} |
Loading…
Reference in new issue