Paranoia2/utils/hlmv/ViewerSettings.cpp
2020-08-31 19:50:41 +03:00

370 lines
9.1 KiB
C++

//
// Half-Life Model Viewer (c) 1999 by Mete Ciragan
//
// file: ViewerSettings.cpp
// last modified: May 29 1999, Mete Ciragan
// copyright: The programs and associated files contained in this
// distribution were developed by Mete Ciragan. The programs
// are not in the public domain, but they are freely
// distributable without licensing fees. These programs are
// provided without guarantee or warrantee expressed or
// implied.
//
// version: 1.2
//
// email: mete@swissquake.ch
// web: http://www.swissquake.ch/chumbalum-soft/
//
#include "ViewerSettings.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mx.h>
#include <time.h>
#include "StudioModel.h"
#include "stringlib.h"
#include <io.h>
#include "conprint.h"
ViewerSettings g_viewerSettings;
void InitViewerSettings( void )
{
memset (&g_viewerSettings, 0, sizeof (ViewerSettings));
g_viewerSettings.renderMode = RM_TEXTURED;
g_viewerSettings.transparency = 1.0f;
g_viewerSettings.movementScale = 1.0f;
g_viewerSettings.enableIK = false;
g_viewerSettings.bgColor[0] = 0.5f;
g_viewerSettings.bgColor[1] = 0.5f;
g_viewerSettings.bgColor[2] = 0.5f;
g_viewerSettings.gColor[0] = 0.85f;
g_viewerSettings.gColor[1] = 0.85f;
g_viewerSettings.gColor[2] = 0.69f;
g_viewerSettings.lColor[0] = 1.0f;
g_viewerSettings.lColor[1] = 1.0f;
g_viewerSettings.lColor[2] = 1.0f;
g_viewerSettings.gLightVec[0] = 0.0f;
g_viewerSettings.gLightVec[1] = 0.0f;
g_viewerSettings.gLightVec[2] = -1.0f;
g_viewerSettings.speedScale = 1.0f;
g_viewerSettings.textureLimit = 256;
g_viewerSettings.showGround = 0;
g_viewerSettings.showMaximized = 0;
g_viewerSettings.textureScale = 1.0f;
g_viewerSettings.sequence_autoplay = true;
g_viewerSettings.studio_blendweights = true;
g_viewerSettings.topcolor = 0;
g_viewerSettings.bottomcolor = 0;
g_viewerSettings.editStep = 1.0f;
g_viewerSettings.editMode = EDIT_SOURCE;
g_viewerSettings.editSize = false;
// init random generator
srand( (unsigned)time( NULL ) );
}
bool InitRegistry( void )
{
return mx::regCreateKey( HKEY_CURRENT_USER, "Software\\XashXT Group\\Paranoia 2 ModelViewer" );
}
bool SaveString( const char *pKey, char *pValue )
{
return mx::regSetValue( HKEY_CURRENT_USER, "Software\\XashXT Group\\Paranoia 2 ModelViewer", pKey, pValue );
}
bool LoadString( const char *pKey, char *pValue )
{
return mx::regGetValue( HKEY_CURRENT_USER, "Software\\XashXT Group\\Paranoia 2 ModelViewer", pKey, pValue );
}
void SaveVector4D( const char *pName, float *pValue )
{
char str[256];
mx_snprintf( str, sizeof( str ), "%g %g %g %g", pValue[0], pValue[1], pValue[2], pValue[3] );
SaveString( pName, str );
}
void LoadVector4D( const char *pName, float *pValue )
{
char str[256];
if( LoadString( pName, str ))
{
sscanf( str, "%g %g %g %g", &pValue[0], &pValue[1], &pValue[2], &pValue[3] );
}
}
void SaveVector3D( const char *pName, float *pValue )
{
char str[256];
mx_snprintf( str, sizeof( str ), "%g %g %g", pValue[0], pValue[1], pValue[2] );
SaveString( pName, str );
}
void LoadVector3D( const char *pName, float *pValue )
{
char str[256];
if( LoadString( pName, str ))
{
sscanf( str, "%g %g %g", &pValue[0], &pValue[1], &pValue[2] );
}
}
void SaveInt( const char *pName, int iValue )
{
char str[256];
mx_snprintf( str, sizeof( str ), "%d", iValue );
SaveString( pName, str );
}
void LoadInt( const char *pName, int *iValue )
{
char str[256];
if( LoadString( pName, str ))
{
sscanf( str, "%d", iValue );
}
}
void SaveFloat( const char *pName, float fValue )
{
char str[256];
mx_snprintf( str, sizeof( str ), "%f", fValue );
SaveString( pName, str );
}
void LoadFloat( const char *pName, float *fValue )
{
char str[256];
if( LoadString( pName, str ))
{
sscanf( str, "%f", fValue );
}
}
int LoadViewerSettings( void )
{
InitViewerSettings ();
LoadVector4D( "Background Color", g_viewerSettings.bgColor );
LoadVector4D( "Light Color", g_viewerSettings.lColor );
LoadVector4D( "Ground Color", g_viewerSettings.gColor );
LoadVector3D( "Light Vector", g_viewerSettings.gLightVec );
LoadInt( "Sequence AutoPlay", &g_viewerSettings.sequence_autoplay );
LoadInt( "Studio BlendWeights", &g_viewerSettings.studio_blendweights );
LoadInt( "Top Color", &g_viewerSettings.topcolor );
LoadInt( "Bottom Color", &g_viewerSettings.bottomcolor );
LoadFloat( "Edit Step", &g_viewerSettings.editStep );
LoadInt( "Edit Mode", &g_viewerSettings.editMode );
LoadInt( "Allow IK", &g_viewerSettings.enableIK );
LoadInt( "Show Ground", &g_viewerSettings.showGround );
LoadString( "Ground TexPath", g_viewerSettings.groundTexFile );
LoadInt( "Show Maximized", &g_viewerSettings.showMaximized );
return 1;
}
int SaveViewerSettings( void )
{
if( !InitRegistry( ))
return 0;
SaveVector4D( "Background Color", g_viewerSettings.bgColor );
SaveVector4D( "Light Color", g_viewerSettings.lColor );
SaveVector4D( "Ground Color", g_viewerSettings.gColor );
SaveVector3D( "Light Vector", g_viewerSettings.gLightVec );
SaveInt( "Sequence AutoPlay", g_viewerSettings.sequence_autoplay );
SaveInt( "Studio BlendWeights", g_viewerSettings.studio_blendweights );
SaveInt( "Top Color", g_viewerSettings.topcolor );
SaveInt( "Bottom Color", g_viewerSettings.bottomcolor );
SaveFloat( "Edit Step", g_viewerSettings.editStep );
SaveInt( "Edit Mode", g_viewerSettings.editMode );
SaveInt( "Allow IK", g_viewerSettings.enableIK );
SaveInt( "Show Ground", g_viewerSettings.showGround );
SaveString( "Ground TexPath", g_viewerSettings.groundTexFile );
SaveInt( "Show Maximized", g_viewerSettings.showMaximized );
return 1;
}
bool IsAliasModel( const char *path )
{
byte buffer[256];
FILE *fp;
if( !path ) return false;
// load the model
if(( fp = fopen( path, "rb" )) == NULL )
return false;
fread( buffer, sizeof( buffer ), 1, fp );
fclose( fp );
if( ftell( fp ) < sizeof( 84 ))
return false;
// skip invalid signature
if( Q_strncmp((const char *)buffer, "IDPO", 4 ))
return false;
// skip unknown version
if( *(int *)&buffer[4] != 6 )
return false;
return true;
}
static bool ValidateModel( const char *path )
{
byte buffer[256];
studiohdr_t *phdr;
FILE *fp;
if( !path ) return false;
// load the model
if(( fp = fopen( path, "rb" )) == NULL )
return false;
fread( buffer, sizeof( buffer ), 1, fp );
fclose( fp );
if( ftell( fp ) < sizeof( studiohdr_t ))
return false;
// skip invalid signature
if( Q_strncmp((const char *)buffer, "IDST", 4 ))
return false;
phdr = (studiohdr_t *)buffer;
// skip unknown version
if( phdr->version != STUDIO_VERSION )
return false;
// skip modelnameT.mdl
if( phdr->numbones <= 0 )
return false;
return true;
}
static void AddPathToList( const char *path )
{
char modelPath[256];
if( g_viewerSettings.numModelPathes >= 2048 )
return; // too many strings
Q_snprintf( modelPath, sizeof( modelPath ), "%s\\%s", g_viewerSettings.oldModelPath, path );
if( !ValidateModel( modelPath ))
return;
int i = g_viewerSettings.numModelPathes++;
Q_strncpy( g_viewerSettings.modelPathList[i], modelPath, sizeof( g_viewerSettings.modelPathList[0] ));
}
static void SortPathList( void )
{
char temp[256];
int i, j;
// this is a selection sort (finds the best entry for each slot)
for( i = 0; i < g_viewerSettings.numModelPathes - 1; i++ )
{
for( j = i + 1; j < g_viewerSettings.numModelPathes; j++ )
{
if( Q_strcmp( g_viewerSettings.modelPathList[i], g_viewerSettings.modelPathList[j] ) > 0 )
{
Q_strncpy( temp, g_viewerSettings.modelPathList[i], sizeof( temp ));
Q_strncpy( g_viewerSettings.modelPathList[i], g_viewerSettings.modelPathList[j], sizeof( temp ));
Q_strncpy( g_viewerSettings.modelPathList[j], temp, sizeof( temp ));
}
}
}
}
void ListDirectory( void )
{
char modelPath[256];
struct _finddata_t n_file;
long hFile;
COM_ExtractFilePath( g_viewerSettings.modelPath, modelPath );
if( !Q_stricmp( modelPath, g_viewerSettings.oldModelPath ))
return; // not changed
Q_strncpy( g_viewerSettings.oldModelPath, modelPath, sizeof( g_viewerSettings.oldModelPath ));
Q_strncat( modelPath, "\\*.mdl", sizeof( modelPath ));
g_viewerSettings.numModelPathes = 0;
// ask for the directory listing handle
hFile = _findfirst( modelPath, &n_file );
if( hFile == -1 ) return; // how this possible?
// start a new chain with the the first name
AddPathToList( n_file.name );
// iterate through the directory
while( _findnext( hFile, &n_file ) == 0 )
AddPathToList( n_file.name );
_findclose( hFile );
SortPathList();
}
const char *LoadNextModel( void )
{
int i;
for( i = 0; i < g_viewerSettings.numModelPathes; i++ )
{
if( !Q_stricmp( g_viewerSettings.modelPathList[i], g_viewerSettings.modelPath ))
{
i++;
break;
}
}
if( i == g_viewerSettings.numModelPathes )
i = 0;
return g_viewerSettings.modelPathList[i];
}
const char *LoadPrevModel( void )
{
int i;
for( i = 0; i < g_viewerSettings.numModelPathes; i++ )
{
if( !Q_stricmp( g_viewerSettings.modelPathList[i], g_viewerSettings.modelPath ))
{
i--;
break;
}
}
if( i < 0 ) i = g_viewerSettings.numModelPathes - 1;
return g_viewerSettings.modelPathList[i];
}