From aeb70b1c6fc3c401da7981ef0b6d4db3b5d081ba Mon Sep 17 00:00:00 2001 From: g-cont Date: Thu, 18 Nov 2010 00:00:00 +0300 Subject: [PATCH] 18 Nov 2010 --- engine/client/cl_game.c | 37 +++-- engine/client/cl_scrn.c | 1 + engine/client/cl_studio.c | 4 + engine/client/client.h | 1 + engine/common/con_utils.c | 24 +++- engine/common/host.c | 2 +- engine/common/input.c | 4 +- engine/common/protocol.h | 2 +- engine/common/vgui_int.cpp | 273 ++++++++++++++++++++++++++----------- game_launch/game.dsp | 8 +- game_launch/game.dsw | 29 ++++ launch/filesystem.c | 2 +- launch/launch.h | 2 +- launch/library.c | 2 +- mainui/menu_creategame.cpp | 2 + vid_gl/r_opengl.c | 4 +- vid_gl/r_studio.c | 2 +- 17 files changed, 291 insertions(+), 108 deletions(-) create mode 100644 game_launch/game.dsw diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index a2482f2d..64dde26a 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -40,8 +40,6 @@ static dllfunc_t cdll_exports[] = { "HUD_ConnectionlessPacket", (void **)&clgame.dllFuncs.pfnConnectionlessPacket }, { "HUD_GetHullBounds", (void **)&clgame.dllFuncs.pfnGetHullBounds }, { "HUD_Frame", (void **)&clgame.dllFuncs.pfnFrame }, -{ "HUD_VoiceStatus", (void **)&clgame.dllFuncs.pfnVoiceStatus }, -{ "HUD_DirectorMessage", (void **)&clgame.dllFuncs.pfnDirectorMessage }, { "HUD_PostRunCmd", (void **)&clgame.dllFuncs.pfnPostRunCmd }, { "HUD_Key_Event", (void **)&clgame.dllFuncs.pfnKey_Event }, { "HUD_AddEntity", (void **)&clgame.dllFuncs.pfnAddEntity }, @@ -51,7 +49,6 @@ static dllfunc_t cdll_exports[] = { "HUD_ProcessPlayerState", (void **)&clgame.dllFuncs.pfnProcessPlayerState }, { "HUD_TxferPredictionData", (void **)&clgame.dllFuncs.pfnTxferPredictionData }, { "HUD_TempEntUpdate", (void **)&clgame.dllFuncs.pfnTempEntUpdate }, -{ "HUD_GetStudioModelInterface", (void **)&clgame.dllFuncs.pfnGetStudioModelInterface }, { "HUD_DrawNormalTriangles", (void **)&clgame.dllFuncs.pfnDrawNormalTriangles }, { "HUD_DrawTransparentTriangles", (void **)&clgame.dllFuncs.pfnDrawTransparentTriangles }, { "HUD_GetUserEntity", (void **)&clgame.dllFuncs.pfnGetUserEntity }, @@ -69,6 +66,14 @@ static dllfunc_t cdll_exports[] = { NULL, NULL } }; +static dllfunc_t cdll_new_exports[] = // allowed only in SDK 2.3 +{ +{ "HUD_GetStudioModelInterface", (void **)&clgame.dllFuncs.pfnGetStudioModelInterface }, +{ "HUD_DirectorMessage", (void **)&clgame.dllFuncs.pfnDirectorMessage }, +{ "HUD_VoiceStatus", (void **)&clgame.dllFuncs.pfnVoiceStatus }, +{ NULL, NULL } +}; + /* ==================== CL_GetEntityByIndex @@ -1835,8 +1840,8 @@ prints dirctly into console (can skip notify) static void pfnConsolePrint( const char *string ) { if( !string || !*string ) return; - if( *string != 1 ) Con_Print( string ); // show notify - else Con_Print( va( "[skipnotify]%s", string + 1 )); // skip notify + if( *string != 1 ) Msg( string ); // show notify + else Msg( "[skipnotify]%s", string + 1 ); // skip notify } /* @@ -3574,9 +3579,10 @@ void CL_UnloadProgs( void ) CL_FreeTempEnts(); CL_FreeViewBeams(); CL_FreeParticles(); + VGui_Shutdown(); clgame.dllFuncs.pfnShutdown(); - + FS_FreeLibrary( clgame.hInstance ); Mem_FreePool( &cls.mempool ); Mem_FreePool( &clgame.mempool ); @@ -3600,6 +3606,11 @@ qboolean CL_LoadProgs( const char *name ) clgame.mempool = Mem_AllocPool( "Client Edicts Zone" ); clgame.entities = NULL; + // NOTE: important stuff! + // vgui must startup BEFORE loading client.dll to avoid get error ERROR_NOACESS + // during LoadLibrary + VGui_Startup (); + clgame.hInstance = FS_LoadLibrary( name, false ); if( !clgame.hInstance ) return false; @@ -3619,6 +3630,18 @@ qboolean CL_LoadProgs( const char *name ) } } + // clear new exports + for( func = cdll_new_exports; func && func->name; func++ ) + *func->func = NULL; + + for( func = cdll_new_exports; func && func->name != NULL; func++ ) + { + // functions are cleared before all the extensions are evaluated + // NOTE: new exports can be missed without stop the engine + if(!( *func->func = (void *)FS_GetProcAddress( clgame.hInstance, func->name ))) + MsgDev( D_NOTE, "CL_LoadProgs: failed to get address of %s proc\n", func->name ); + } + if( !clgame.dllFuncs.pfnInitialize( &gEngfuncs, CLDLL_INTERFACE_VERSION )) { FS_FreeLibrary( clgame.hInstance ); @@ -3643,8 +3666,6 @@ qboolean CL_LoadProgs( const char *name ) CL_InitViewBeams (); CL_InitTempEnts (); - VGui_Startup (); - // initialize game clgame.dllFuncs.pfnInit(); diff --git a/engine/client/cl_scrn.c b/engine/client/cl_scrn.c index 36f58995..360268fc 100644 --- a/engine/client/cl_scrn.c +++ b/engine/client/cl_scrn.c @@ -261,6 +261,7 @@ void SCR_UpdateScreen( void ) if( !clgame.hInstance ) return; clgame.dllFuncs.pfnFrame( cl.time ); + VGui_Paint (); } diff --git a/engine/client/cl_studio.c b/engine/client/cl_studio.c index 878c63c3..60cfdafd 100644 --- a/engine/client/cl_studio.c +++ b/engine/client/cl_studio.c @@ -511,6 +511,10 @@ Initialize client studio */ qboolean CL_InitStudioAPI( void ) { + // Xash will be used internal StudioModelRenderer + if( !clgame.dllFuncs.pfnGetStudioModelInterface ) + return true; + pStudioDraw = NULL; // clear previous API return clgame.dllFuncs.pfnGetStudioModelInterface( STUDIO_INTERFACE_VERSION, &pStudioDraw, &gStudioAPI ); diff --git a/engine/client/client.h b/engine/client/client.h index 3da61110..4f233242 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -690,6 +690,7 @@ extern "C" { #endif void VGui_Startup( void ); +void VGui_Shutdown( void ); void *VGui_GetPanel( void ); void VGui_Paint( void ); void VGui_ViewportPaintBackground( int extents[4] ); diff --git a/engine/common/con_utils.c b/engine/common/con_utils.c index bc2fed1e..d0aa1888 100644 --- a/engine/common/con_utils.c +++ b/engine/common/con_utils.c @@ -705,19 +705,19 @@ qboolean Cmd_GetGamesList( const char *s, char *completedname, int length ) return true; } -qboolean Cmd_CheckMapsList( qboolean fRefresh ) +qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir ) { - byte buf[MAX_MSGLEN]; + byte buf[MAX_SYSPATH]; char *buffer; string result; + int i, size; search_t *t; file_t *f; - int i; - if( FS_FileExistsEx( "maps.lst", true ) && !fRefresh ) + if( FS_FileSizeEx( "maps.lst", onlyingamedir ) > 0 && !fRefresh ) return true; // exist - t = FS_SearchExt( "maps/*.bsp", false, true ); + t = FS_SearchExt( "maps/*.bsp", false, onlyingamedir ); if( !t ) return false; buffer = Mem_Alloc( host.mempool, t->numfilenames * 2 * sizeof( result )); @@ -729,7 +729,7 @@ qboolean Cmd_CheckMapsList( qboolean fRefresh ) const char *ext = FS_FileExtension( t->filenames[i] ); if( com.stricmp( ext, "bsp" )) continue; - f = FS_OpenEx( t->filenames[i], "rb", true ); + f = FS_OpenEx( t->filenames[i], "rb", onlyingamedir ); FS_FileBase( t->filenames[i], mapname ); if( f ) @@ -817,6 +817,13 @@ qboolean Cmd_CheckMapsList( qboolean fRefresh ) } if( t ) Mem_Free( t ); // free search result + size = com.strlen( buffer ); + if( !size && onlyingamedir ) + { + if( buffer ) Mem_Free( buffer ); + return Cmd_CheckMapsList_R( fRefresh, false ); + } + // write generated maps.lst if( FS_WriteFile( "maps.lst", buffer, com.strlen( buffer ))) { @@ -826,6 +833,11 @@ qboolean Cmd_CheckMapsList( qboolean fRefresh ) return false; } +qboolean Cmd_CheckMapsList( qboolean fRefresh ) +{ + return Cmd_CheckMapsList_R( fRefresh, true ); +} + autocomplete_list_t cmd_list[] = { { "gl_texturemode", Cmd_GetTexturemodes }, diff --git a/engine/common/host.c b/engine/common/host.c index 5a332274..10c497f2 100644 --- a/engine/common/host.c +++ b/engine/common/host.c @@ -833,7 +833,7 @@ void Host_Init( const int argc, const char **argv ) if( host.type != HOST_DEDICATED ) { - // NOTE: client.dll must be loaded first to get mlook state from congig.cfg + // NOTE: client.dll must be loaded first to get mlook state from config.cfg if( !CL_LoadProgs( va( "%s/client.dll", GI->dll_path ))) Host_Error( "CL_InitGame: can't initialize client.dll\n" ); diff --git a/engine/common/input.c b/engine/common/input.c index 0f391535..5b56de15 100644 --- a/engine/common/input.c +++ b/engine/common/input.c @@ -456,8 +456,8 @@ long IN_WndProc( void *hWnd, uint uMsg, uint wParam, long lParam ) break; case WM_CREATE: host.hWnd = hWnd; - scr_xpos = Cvar_Get( "r_xpos", "3", CVAR_ARCHIVE, "window position by horizontal" ); - scr_ypos = Cvar_Get( "r_ypos", "22", CVAR_ARCHIVE, "window position by vertical" ); + scr_xpos = Cvar_Get( "r_xpos", "130", CVAR_ARCHIVE, "window position by horizontal" ); + scr_ypos = Cvar_Get( "r_ypos", "48", CVAR_ARCHIVE, "window position by vertical" ); scr_fullscreen = Cvar_Get( "fullscreen", "0", CVAR_ARCHIVE|CVAR_LATCH_VIDEO, "toggle fullscreen" ); GetWindowRect( host.hWnd, &real_rect ); break; diff --git a/engine/common/protocol.h b/engine/common/protocol.h index a5fec11f..bb77682c 100644 --- a/engine/common/protocol.h +++ b/engine/common/protocol.h @@ -5,7 +5,7 @@ #ifndef PROTOCOL_H #define PROTOCOL_H -#define PROTOCOL_VERSION 39 +#define PROTOCOL_VERSION 40 // server to client #define svc_bad 0 // immediately crash client when received diff --git a/engine/common/vgui_int.cpp b/engine/common/vgui_int.cpp index f5125ef5..6b594f1d 100644 --- a/engine/common/vgui_int.cpp +++ b/engine/common/vgui_int.cpp @@ -11,99 +11,158 @@ #include #include #include -#include -#include #include #include using namespace vgui; -SurfaceGL::SurfaceGL( Panel* embeddedPanel ):Surface( embeddedPanel ) +class CEngineSurface : public SurfaceBase { - _embeddedPanel = embeddedPanel; -} +public: + CEngineSurface( Panel *embeddedPanel ):SurfaceBase( embeddedPanel ) + { + _embeddedPanel = embeddedPanel; + } +public: + virtual void setTitle( const char *title ) + { + Msg( "SetTitle: %s\n", title ); + } -void SurfaceGL::texturedRect( int x0, int y0, int x1, int y1 ) -{ - Msg( "texturedRect: %i %i %i %i\n", x0, y0, x1, y1 ); -} - -bool SurfaceGL:: recreateContext() -{ - return true; -} - -void SurfaceGL:: createPopup( Panel *embeddedPanel ) -{ -} + virtual bool setFullscreenMode( int wide, int tall, int bpp ) + { + return false; + } -void SurfaceGL:: pushMakeCurrent( Panel* panel, bool useInsets ) -{ -} + virtual void setWindowedMode( void ) + { + } -void SurfaceGL:: popMakeCurrent( Panel* panel ) -{ -} + virtual void setAsTopMost( bool state ) + { + } -void SurfaceGL:: makeCurrent( void ) -{ -} + virtual int getModeInfoCount( void ) + { + Msg( "getModeInfoCount()\n" ); + return 0; + } -void SurfaceGL::swapBuffers( void ) -{ -} + virtual void createPopup( Panel* embeddedPanel ) + { + } -void SurfaceGL::setColor( int r, int g, int b ) -{ -} + virtual bool hasFocus( void ) + { + Msg( "hasFocus()\n" ); + return false; + } -void SurfaceGL::filledRect( int x0, int y0, int x1, int y1 ) -{ -} + virtual bool isWithin( int x, int y ) + { + Msg( "isWithin()\n" ); + return false; + } +protected: + virtual int createNewTextureID( void ) + { + Msg( "createNewTextureID()\n" ); + return 0; + } -void SurfaceGL::outlinedRect( int x0, int y0, int x1, int y1 ) -{ -} + virtual void drawSetColor( int r, int g, int b, int a ) + { + } -void SurfaceGL::setTextFont( Font* font ) -{ -} + virtual void drawFilledRect( int x0, int y0, int x1, int y1 ) + { + } -void SurfaceGL::setTextColor( int r, int g, int b ) -{ - Msg( "setTextColor: %i %i %i\n", r, g, b ); -} + virtual void drawOutlinedRect( int x0,int y0,int x1,int y1 ) + { + } + + virtual void drawSetTextFont( Font *font ) + { + } -void SurfaceGL::setDrawPos( int x, int y ) -{ - Msg( "setDrawPos: %i %i\n", x, y ); -} + virtual void drawSetTextColor( int r, int g, int b, int a ) + { + } -void SurfaceGL::printText( const char *str, int strlen ) -{ - Msg( "printText: %s\n", str ); -} + virtual void drawSetTextPos( int x, int y ) + { + } -void SurfaceGL::setTextureRGBA( int id, const char *rgba, int wide, int tall ) -{ - Msg( "setTextureRGBA: %i\n", id ); -} + virtual void drawPrintText( const char* text, int textLen ) + { + } -void SurfaceGL::setTexture( int id ) -{ - Msg( "setTexture: %i\n", id ); -} + 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 invalidate( Panel *panel ) + { + } + + virtual bool createPlat() + { + return false; + } + + virtual bool recreateContext() + { + return false; + } + + virtual void enableMouseCapture(bool state) + { + } + + virtual void setCursor(Cursor* cursor) + { + } + + virtual void swapBuffers() + { + } + + virtual void pushMakeCurrent(Panel* panel,bool useInsets) + { + } + + virtual void popMakeCurrent(Panel* panel) + { + } + + virtual void applyChanges( void ) + { + } +protected: + friend class App; + friend class Panel; +}; class CEngineApp : public App { public: CEngineApp( void ) { - reset(); + App::reset(); } virtual void main( int argc, char* argv[] ) { + Msg( "App main()\n" ); } virtual void setCursorPos( int x, int y ) @@ -116,51 +175,105 @@ public: App::getCursorPos( x, y ); Msg( "getCursorPos: %i %i\n", x, y ); } -}; - -class CEnginePanel : public Panel, public CEngineApp -{ - typedef Panel BaseClass; -public: - CEnginePanel( void ) + virtual App* getApp( void ) { - _surfaceBase = new SurfaceGL( this ); - setSurfaceBaseTraverse( _surfaceBase ); - setParent( NULL ); + return this; } }; +CEngineSurface *surface = NULL; +CEngineApp *pApp = NULL; + +class CEnginePanel : public Panel +{ +public: + CEnginePanel() + { + vgui::Panel(); + } + CEnginePanel( int x, int y, int wide, int tall ) + { + vgui::Panel( x, y, wide, tall ); + } + virtual SurfaceBase* getSurfaceBase( void ) + { + return surface; + } + virtual App* getApp( void ) + { + return pApp; + } + virtual void paintBackground( void ) + { + for( int i = 0; i < getChildCount(); i++ ) + { + Panel *pChild = getChild( i ); + pChild->repaintAll(); + } + } +friend class Panel; +friend class App; +friend class SurfaceBase; +friend class Image; +}; + CEnginePanel *rootpanel = NULL; void VGui_Startup( void ) { if( rootpanel ) { - rootpanel->reset(); +// rootpanel->reset(); rootpanel->setSize( menu.globals->scrWidth, menu.globals->scrHeight ); return; } - rootpanel = new CEnginePanel(); - rootpanel->setLayout( new BorderLayout( 0 )); - rootpanel->setEnabled( true ); + rootpanel = new CEnginePanel; + rootpanel->setPaintBorderEnabled( false ); + rootpanel->setPaintBackgroundEnabled( false ); rootpanel->setVisible( true ); + rootpanel->setCursor( new Cursor( Cursor::dc_none )); + + pApp = new CEngineApp; + pApp->setMinimumTickMillisInterval( 0 ); + + surface = new CEngineSurface( rootpanel ); ASSERT( rootpanel->getApp() != NULL ); ASSERT( rootpanel->getSurfaceBase() != NULL ); } +void VGui_Shutdown( void ) +{ + delete rootpanel; + delete surface; + delete pApp; + + rootpanel = NULL; + surface = NULL; + pApp = NULL; +} + void VGui_Paint( void ) { if( !rootpanel ) return; - rootpanel->solveTraverse(); - rootpanel->paintTraverse(); + rootpanel->paintBackground(); } void VGui_ViewportPaintBackground( int extents[4] ) { - Msg( "paint()\n" ); + if( !rootpanel ) return; + + Msg( "ViewportPaintBackground()\n" ); + Panel *pVPanel = surface->getPanel(); + if( !pVPanel ) return; + + rootpanel->setBounds( extents[0], extents[1], extents[2], extents[3] ); + rootpanel->repaint(); + + // paint everything + rootpanel->paintTraverse(); } void *VGui_GetPanel( void ) diff --git a/game_launch/game.dsp b/game_launch/game.dsp index 9e25e2a0..18a0773f 100644 --- a/game_launch/game.dsp +++ b/game_launch/game.dsp @@ -4,7 +4,7 @@ # TARGTYPE "Win32 (x86) Application" 0x0101 -CFG=LAUNCH - WIN32 RELEASE +CFG=game - Win32 Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE @@ -13,7 +13,7 @@ CFG=LAUNCH - WIN32 RELEASE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "game.mak" CFG="LAUNCH - WIN32 RELEASE" +!MESSAGE NMAKE /f "game.mak" CFG="game - Win32 Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE @@ -59,11 +59,11 @@ LINK32=link.exe # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File -SOURCE=.\game.rc +SOURCE=.\game.cpp # End Source File # Begin Source File -SOURCE=.\game.cpp +SOURCE=.\game.rc # End Source File # End Group # Begin Group "Header Files" diff --git a/game_launch/game.dsw b/game_launch/game.dsw new file mode 100644 index 00000000..330b7b6e --- /dev/null +++ b/game_launch/game.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "game"=.\game.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/launch/filesystem.c b/launch/filesystem.c index 5463fb93..ff17ea10 100644 --- a/launch/filesystem.c +++ b/launch/filesystem.c @@ -1904,7 +1904,7 @@ void FS_InitRootDir( char *path ) // just set cwd GetModuleFileName( NULL, szTemp, MAX_SYSPATH ); FS_ExtractFilePath( szTemp, szTemp ); - SetCurrentDirectory ( szTemp ); + SetCurrentDirectory( szTemp ); // use extended pathname fs_ext_path = true; diff --git a/launch/launch.h b/launch/launch.h index c22c5173..756a7319 100644 --- a/launch/launch.h +++ b/launch/launch.h @@ -19,7 +19,7 @@ #define LAUNCH_DLL // ignore alias names #include "launch_api.h" -#define XASH_VERSION 0.72f // current version will be shared across gameinfo struct +#define XASH_VERSION 0.73f // current version will be shared across gameinfo struct #define MAX_NUM_ARGVS 128 #define MAX_CMD_TOKENS 80 diff --git a/launch/library.c b/launch/library.c index 3c31ee45..194ab7af 100644 --- a/launch/library.c +++ b/launch/library.c @@ -760,7 +760,7 @@ void *Com_LoadLibraryExt( const char *dllname, int build_ordinals_table, qboolea if( !hInst->hInstance ) { - MsgDev( D_NOTE, "Sys_LoadLibrary: Loading %s - failed\n", dllname ); + MsgDev( D_NOTE, "Sys_LoadLibrary: Loading %s - failed. Error %i\n", dllname ); Com_FreeLibrary( hInst ); return NULL; } diff --git a/mainui/menu_creategame.cpp b/mainui/menu_creategame.cpp index bd450bc4..c9abf827 100644 --- a/mainui/menu_creategame.cpp +++ b/mainui/menu_creategame.cpp @@ -204,6 +204,8 @@ static void UI_CreateGame_GetMapsList( void ) numMaps++; } + if( !numMaps ) uiCreateGame.done.generic.flags |= QMF_GRAYED; + for( ; numMaps < UI_MAXGAMES; numMaps++ ) uiCreateGame.mapsDescriptionPtr[numMaps] = NULL; uiCreateGame.mapsList.itemNames = (const char **)uiCreateGame.mapsDescriptionPtr; FREE_FILE( afile ); diff --git a/vid_gl/r_opengl.c b/vid_gl/r_opengl.c index 5edcbf26..a1c5e084 100644 --- a/vid_gl/r_opengl.c +++ b/vid_gl/r_opengl.c @@ -494,8 +494,8 @@ qboolean R_CreateWindow( int width, int height, qboolean fullscreen ) if( !fullscreen ) { - r_xpos = Cvar_Get( "r_xpos", "3", CVAR_ARCHIVE, "window position by horizontal" ); - r_ypos = Cvar_Get( "r_ypos", "22", CVAR_ARCHIVE, "window position by vertical" ); + r_xpos = Cvar_Get( "r_xpos", "130", CVAR_ARCHIVE, "window position by horizontal" ); + r_ypos = Cvar_Get( "r_ypos", "48", CVAR_ARCHIVE, "window position by vertical" ); x = r_xpos->integer; y = r_ypos->integer; diff --git a/vid_gl/r_studio.c b/vid_gl/r_studio.c index 3e85a60b..e344d146 100644 --- a/vid_gl/r_studio.c +++ b/vid_gl/r_studio.c @@ -1758,7 +1758,7 @@ qboolean R_StudioComputeBBox( vec3_t bbox[8] ) if( p2[2] > studio_maxs[2] ) studio_maxs[2] = p2[2]; } - studio_radius = RadiusFromBounds( studio_mins, studio_maxs ); + studio_radius = RadiusFromBounds( studio_mins, studio_maxs ) * e->scale; return true; }