xash3d-fwgs/engine/client/vgui/vgui_draw.c

773 lines
20 KiB
C
Raw Normal View History

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