This commit is contained in:
OM 2023-05-25 19:34:01 +02:00
parent c32c377946
commit f013e82b98
4 changed files with 261 additions and 45 deletions

View file

@ -141,6 +141,7 @@ set(SOURCES_COMMON
"code/qcommon/memory.c"
"code/qcommon/msg.cpp"
"code/qcommon/net_chan.c"
"code/qcommon/net_ip.c"
"code/qcommon/q_math.c"
"code/qcommon/q_shared.c"
"code/qcommon/tiki_main.cpp"

View file

@ -39,7 +39,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
qboolean CL_FinishedIntro(void);
void UI_PrintConsole(const char* msg);
#ifdef __cplusplus
extern "C" {
#endif
cvar_t *sv_scriptfiles;
cvar_t *g_scriptcheck;
@ -1917,45 +1919,59 @@ void Com_WipeSavegame( const char *savename )
//------------------------------------------------------------------------
/*
===========================================
command line completion
===========================================
*/
/*
==================
Field_Clear
==================
*/
void Field_Clear(field_t* edit) {
memset(edit->buffer, 0, MAX_EDIT_LINE);
edit->cursor = 0;
edit->scroll = 0;
}
static const char *completionString;
static const char* completionString;
static char shortestMatch[MAX_TOKEN_CHARS];
static int matchCount;
// field we are working on, passed to Field_AutoComplete(&g_consoleCommand for instance)
static field_t* completionField;
/*
===============
FindMatches
===============
*/
static void FindMatches( const char *s ) {
int i;
static void FindMatches(const char* s) {
int i;
if ( Q_stricmpn( s, completionString, strlen( completionString ) ) ) {
return;
}
matchCount++;
if ( matchCount == 1 ) {
Q_strncpyz( shortestMatch, s, sizeof( shortestMatch ) );
return;
}
if (Q_stricmpn(s, completionString, strlen(completionString))) {
return;
}
matchCount++;
if (matchCount == 1) {
Q_strncpyz(shortestMatch, s, sizeof(shortestMatch));
return;
}
// cut shortestMatch to the amount common with s
for ( i = 0 ; shortestMatch[i] ; i++ ) {
if ( i >= strlen( s ) ) {
shortestMatch[i] = 0;
break;
}
// cut shortestMatch to the amount common with s
for (i = 0; shortestMatch[i]; i++) {
if (i >= strlen(s)) {
shortestMatch[i] = 0;
break;
}
if ( tolower(shortestMatch[i]) != tolower(s[i]) ) {
shortestMatch[i] = 0;
}
}
if (tolower(shortestMatch[i]) != tolower(s[i])) {
shortestMatch[i] = 0;
}
}
}
/*
@ -1964,10 +1980,10 @@ PrintMatches
===============
*/
static void PrintMatches( const char *s ) {
if ( !Q_stricmpn( s, shortestMatch, strlen( shortestMatch ) ) ) {
Com_Printf( " %s\n", s );
}
static void PrintMatches(const char* s) {
if (!Q_stricmpn(s, shortestMatch, strlen(shortestMatch))) {
Com_Printf(" %s\n", s);
}
}
/*
@ -1976,13 +1992,205 @@ PrintCvarMatches
===============
*/
static void PrintCvarMatches( const char *s ) {
char value[ TRUNCATE_LENGTH ];
static void PrintCvarMatches(const char* s) {
char value[TRUNCATE_LENGTH];
if ( !Q_stricmpn( s, shortestMatch, strlen( shortestMatch ) ) ) {
Com_TruncateLongString( value, Cvar_VariableString( s ) );
Com_Printf( " %s = \"%s\"\n", s, value );
}
if (!Q_stricmpn(s, shortestMatch, strlen(shortestMatch))) {
Com_TruncateLongString(value, Cvar_VariableString(s));
Com_Printf(" %s = \"%s\"\n", s, value);
}
}
/*
===============
Field_FindFirstSeparator
===============
*/
static char* Field_FindFirstSeparator(char* s)
{
int i;
for (i = 0; i < strlen(s); i++)
{
if (s[i] == ';')
return &s[i];
}
return NULL;
}
/*
===============
Field_Complete
===============
*/
static qboolean Field_Complete(void)
{
int completionOffset;
if (matchCount == 0)
return qtrue;
completionOffset = strlen(completionField->buffer) - strlen(completionString);
Q_strncpyz(&completionField->buffer[completionOffset], shortestMatch,
sizeof(completionField->buffer) - completionOffset);
completionField->cursor = strlen(completionField->buffer);
if (matchCount == 1)
{
Q_strcat(completionField->buffer, sizeof(completionField->buffer), " ");
completionField->cursor++;
return qtrue;
}
Com_Printf("]%s\n", completionField->buffer);
return qfalse;
}
#ifndef DEDICATED
/*
===============
Field_CompleteKeyname
===============
*/
void Field_CompleteKeyname(void)
{
matchCount = 0;
shortestMatch[0] = 0;
Key_KeynameCompletion(FindMatches);
if (!Field_Complete())
Key_KeynameCompletion(PrintMatches);
}
#endif
/*
===============
Field_CompleteFilename
===============
*/
void Field_CompleteFilename(const char* dir,
const char* ext, qboolean stripExt, qboolean allowNonPureFilesOnDisk)
{
matchCount = 0;
shortestMatch[0] = 0;
FS_FilenameCompletion(dir, ext, stripExt, FindMatches, allowNonPureFilesOnDisk);
if (!Field_Complete())
FS_FilenameCompletion(dir, ext, stripExt, PrintMatches, allowNonPureFilesOnDisk);
}
/*
===============
Field_CompleteCommand
===============
*/
void Field_CompleteCommand(char* cmd,
qboolean doCommands, qboolean doCvars)
{
int completionArgument = 0;
// Skip leading whitespace and quotes
cmd = Com_SkipCharset(cmd, " \"");
Cmd_TokenizeStringIgnoreQuotes(cmd);
completionArgument = Cmd_Argc();
// If there is trailing whitespace on the cmd
if (*(cmd + strlen(cmd) - 1) == ' ')
{
completionString = "";
completionArgument++;
}
else
completionString = Cmd_Argv(completionArgument - 1);
#ifndef DEDICATED
// add a '\' to the start of the buffer if it might be sent as chat otherwise
if (con_autochat->integer && completionField->buffer[0] &&
completionField->buffer[0] != '\\')
{
if (completionField->buffer[0] != '/')
{
// Buffer is full, refuse to complete
if (strlen(completionField->buffer) + 1 >=
sizeof(completionField->buffer))
return;
memmove(&completionField->buffer[1],
&completionField->buffer[0],
strlen(completionField->buffer) + 1);
completionField->cursor++;
}
completionField->buffer[0] = '\\';
}
#endif
if (completionArgument > 1)
{
const char* baseCmd = Cmd_Argv(0);
char* p;
#ifndef DEDICATED
// This should always be true
if (baseCmd[0] == '\\' || baseCmd[0] == '/')
baseCmd++;
#endif
if ((p = Field_FindFirstSeparator(cmd)))
Field_CompleteCommand(p + 1, qtrue, qtrue); // Compound command
else
Cmd_CompleteArgument(baseCmd, cmd, completionArgument);
}
else
{
if (completionString[0] == '\\' || completionString[0] == '/')
completionString++;
matchCount = 0;
shortestMatch[0] = 0;
if (strlen(completionString) == 0)
return;
if (doCommands)
Cmd_CommandCompletion(FindMatches);
if (doCvars)
Cvar_CommandCompletion(FindMatches);
if (!Field_Complete())
{
// run through again, printing matches
if (doCommands)
Cmd_CommandCompletion(PrintMatches);
if (doCvars)
Cvar_CommandCompletion(PrintCvarMatches);
}
}
}
/*
===============
Field_AutoComplete
Perform Tab expansion
===============
*/
void Field_AutoComplete(field_t* field)
{
completionField = field;
Field_CompleteCommand(completionField->buffer, qtrue, qtrue);
}
#ifdef __cplusplus
}
#endif

View file

@ -385,8 +385,6 @@ typedef enum {
TRAP_TESTPRINTFLOAT
} sharedTraps_t;
typedef intptr_t (QDECL *vmMainProc)(int callNum, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11);
void VM_Init( void );
vm_t *VM_Create( const char *module, intptr_t (*systemCalls)(intptr_t *),
vmInterpret_t interpret );
@ -473,6 +471,17 @@ void Cmd_AddCommand( const char *cmd_name, xcommand_t function );
void Cmd_RemoveCommand( const char *cmd_name );
typedef void (*completionFunc_t)( char *args, int argNum );
// don't allow VMs to remove system commands
void Cmd_RemoveCommandSafe( const char *cmd_name );
void Cmd_CommandCompletion( void(*callback)(const char *s) );
// callback with each valid string
void Cmd_SetCommandCompletionFunc( const char *command,
completionFunc_t complete );
void Cmd_CompleteArgument( const char *command, char *args, int argNum );
void Cmd_CompleteCfgName( char *args, int argNum );
void Cmd_CommandCompletion( void(*callback)(const char *s) );
// callback with each valid string
@ -483,6 +492,7 @@ char *Cmd_Args (void);
char *Cmd_ArgsFrom( int arg );
void Cmd_ArgsBuffer( char *buffer, int bufferLength );
char *Cmd_Cmd (void);
void Cmd_Args_Sanitize( void );
// The functions that execute commands get their parameters with these
// functions. Cmd_Argv () will return an empty string, not a NULL
// if arg > argc, so string operations are allways safe.
@ -492,9 +502,7 @@ void Cmd_TokenizeStringIgnoreQuotes( const char *text_in );
// Takes a null terminated string. Does not need to be /n terminated.
// breaks the string up into arg tokens.
const char *Cmd_CompleteCommand( const char *partial );
const char *Cmd_CompleteCommandByNumber( const char *partial, int number );
void Cmd_ExecuteString( const char *text );
void Cmd_ExecuteString( const char *text );
// Parses a single line of text into arguments and tries to execute it
// as if it was typed at the console
@ -774,7 +782,7 @@ void FS_Rename( const char *from, const char *to );
void FS_Remove( const char *osPath );
void FS_FilenameCompletion( const char *dir, const char *ext,
qboolean stripExt, void(*callback)(const char *s) );
qboolean stripExt, void(*callback)(const char *s), qboolean allowNonPureFilesOnDisk );
const char* FS_GetCurrentGameDir();
void FS_GetRelativeFilename( const char *currentDirectory, const char *absoluteFilename, char *out, size_t destlen );
@ -792,13 +800,6 @@ MISC
==============================================================
*/
#define MAX_EDIT_LINE 256
typedef struct {
int cursor;
int scroll;
int widthInChars;
char buffer[MAX_EDIT_LINE];
} field_t;
// returnbed by Sys_GetProcessorId
#define CPUID_GENERIC 0 // any unrecognized processor
@ -1207,7 +1208,7 @@ qboolean Sys_StringToAdr( const char *s, netadr_t *a );
qboolean Sys_IsLANAddress (netadr_t adr);
void Sys_ShowIP(void);
qboolean Sys_Mkdir( const char *path );
void Sys_Mkdir( const char *path );
char *Sys_Cwd( void );
void Sys_SetDefaultInstallPath(const char *path);
char *Sys_DefaultInstallPath( void );

View file

@ -275,6 +275,12 @@ void* Sys_GetCGameAPI(void* parms)
return GetCGameAPI(parms);
}
void VM_Forced_Unload_Start(void) {
}
void VM_Forced_Unload_Done(void) {
}
void Sys_InitEx()
{
Sys_InitLocalization();