22 Nov 2007

This commit is contained in:
g-cont 2007-11-22 00:00:00 +03:00 committed by Alibek Omarov
parent 3c807c94e4
commit 6a0928281c
28 changed files with 850 additions and 261 deletions

View File

@ -26,10 +26,13 @@ scroll = visible_offset
Имплементация нового меню
1. перенести все ресурсы из версии 0.4
2. разобраться с short->word конверсией VM
//==================================================
// то, что уже готово
//==================================================
+добавлен Sys_Crash
+исправлен баг с рекурсивным вызовом Sys_Error и Host_Error
+имплементированы простейшие сохранялки
+qcclib создает progs.src
+исправлен баг в stdlib.c

View File

@ -1343,7 +1343,7 @@ void CIN_DrawCinematic( void )
Cinematic user interface
==============================================================================
*/
void SCR_PlayCinematic( char *name, int bits )
bool SCR_PlayCinematic( char *name, int bits )
{
if (cls.state == ca_cinematic)
SCR_StopCinematic();
@ -1351,7 +1351,11 @@ void SCR_PlayCinematic( char *name, int bits )
S_StopAllSounds();
if (CIN_PlayCinematic( name, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, bits ))
{
SCR_RunCinematic(); // load first frame
return true;
}
return false;
}
void SCR_DrawCinematic( void )
@ -1370,6 +1374,16 @@ void SCR_StopCinematic( void )
S_StopAllSounds();
}
void SCR_ResetCinematic( void )
{
RoQReset();
}
int SCR_GetCinematicState( void )
{
return cinTable.status;
}
/*
====================
SCR_FinishCinematic

View File

@ -450,20 +450,18 @@ void CL_Connect_f (void)
return;
}
if (Host_ServerState ())
{ // if running a local server, kill it and reissue
SV_Shutdown (va("Server quit\n", msg), false);
}
else
{
CL_Disconnect ();
if(Host_ServerState())
{
// if running a local server, kill it and reissue
std.strncpy( host.finalmsg, "Server quit\n", MAX_STRING );
SV_Shutdown( false );
}
else CL_Disconnect();
server = Cmd_Argv (1);
NET_Config (true); // allow remote
CL_Disconnect ();
NET_Config( true ); // allow remote
CL_Disconnect();
cls.state = ca_connecting;
strncpy (cls.servername, server, sizeof(cls.servername)-1);

View File

@ -649,10 +649,12 @@ int Key_GetKey( char *binding );
//
// cl_cin.c
//
void SCR_PlayCinematic( char *name, int bits );
bool SCR_PlayCinematic( char *name, int bits );
void SCR_DrawCinematic( void );
void SCR_RunCinematic( void );
void SCR_StopCinematic( void );
void SCR_ResetCinematic( void );
int SCR_GetCinematicState( void );
void SCR_FinishCinematic( void );
#endif//CLIENT_H

View File

@ -155,7 +155,7 @@ typedef struct prvm_prog_s
//============================================================================
// until this point everything also exists (with the pr_ prefix) in the old vm
file_t *openfiles[PRVM_MAX_OPENFILES];
vfile_t *openfiles[PRVM_MAX_OPENFILES];
search_t *opensearches[PRVM_MAX_OPENSEARCHES];
// copies of some vars that were former read from sv

View File

@ -213,6 +213,23 @@ void VM_sprint( void )
SV_ClientPrintf (svs.clients+(num - 1), PRINT_HIGH, "%s", string );
}
/*
=================
VM_centerprint
single print to the screen
centerprint(clientent, value)
=================
*/
void VM_centerprint( void )
{
char string[VM_STRINGTEMP_LENGTH];
VM_VarString(0, string, sizeof(string));
CG_CenterPrint( string, SCREEN_HEIGHT/2, BIGCHAR_WIDTH );
}
void VM_servercmd (void)
{
char string[VM_STRINGTEMP_LENGTH];
@ -1376,18 +1393,23 @@ void VM_Files_Init(void)
prog->openfiles[i] = NULL;
}
void VM_Files_CloseAll(void)
void VM_Files_CloseAll( void )
{
int i;
for (i = 0;i < PRVM_MAX_OPENFILES;i++)
int i;
file_t *f;
for(i = 0; i < PRVM_MAX_OPENFILES; i++)
{
if (prog->openfiles[i])
FS_Close(prog->openfiles[i]);
{
f = VFS_Close(prog->openfiles[i]);
FS_Close( f ); // close real file too
}
prog->openfiles[i] = NULL;
}
}
file_t *VM_GetFileHandle( int index )
vfile_t *VM_GetFileHandle( int index )
{
if (index < 0 || index >= PRVM_MAX_OPENFILES)
{
@ -1412,20 +1434,21 @@ float fopen(string filename, float mode)
// float(string filename, float mode) fopen = #110;
// opens a file inside quake/gamedir/data/ (mode is FILE_READ, FILE_APPEND, or FILE_WRITE),
// returns fhandle >= 0 if successful, or fhandle < 0 if unable to open file for any reason
void VM_fopen(void)
void VM_fopen( void )
{
int filenum, mode;
const char *modestring, *filename;
int filenum, mode;
const char *modestring, *filename;
VM_SAFEPARMCOUNT(2,VM_fopen);
VM_SAFEPARMCOUNT(2, VM_fopen);
for (filenum = 0;filenum < PRVM_MAX_OPENFILES;filenum++)
for (filenum = 0; filenum < PRVM_MAX_OPENFILES; filenum++)
if (prog->openfiles[filenum] == NULL)
break;
if (filenum >= PRVM_MAX_OPENFILES)
{
PRVM_G_FLOAT(OFS_RETURN) = -2;
VM_Warning("VM_fopen: %s ran out of file handles (%i)\n", PRVM_NAME, PRVM_MAX_OPENFILES);
VM_Warning("VM_fopen: %s ran out of file handles(%i)\n", PRVM_NAME, PRVM_MAX_OPENFILES);
return;
}
mode = (int)PRVM_G_FLOAT(OFS_PARM1);
@ -1440,27 +1463,30 @@ void VM_fopen(void)
case 2: // FILE_WRITE
modestring = "wb";
break;
case 3: // FILE_WRITE_DEFLATED
modestring = "wz";
break;
default:
PRVM_G_FLOAT(OFS_RETURN) = -3;
VM_Warning("VM_fopen: %s: no such mode %i (valid: 0 = read, 1 = append, 2 = write)\n", PRVM_NAME, mode);
VM_Warning("VM_fopen: %s: no such mode %i (valid: 0 = read, 1 = append, 2 = write, 3 = deflate)\n", PRVM_NAME, mode);
return;
}
filename = PRVM_G_STRING(OFS_PARM0);
prog->openfiles[filenum] = FS_Open(va("data/%s", filename), modestring );
prog->openfiles[filenum] = VFS_Open(FS_Open(va("temp/%s", filename), modestring), modestring );
if (prog->openfiles[filenum] == NULL && mode == 0)
prog->openfiles[filenum] = FS_Open(va("%s", filename), modestring );
prog->openfiles[filenum] = VFS_Open(FS_Open(va("%s", filename), modestring), modestring );
if (prog->openfiles[filenum] == NULL)
{
PRVM_G_FLOAT(OFS_RETURN) = -1;
if (host.developer >= D_WARN)
if(host.developer >= D_WARN)
VM_Warning("VM_fopen: %s: %s mode %s failed\n", PRVM_NAME, filename, modestring);
}
else
{
PRVM_G_FLOAT(OFS_RETURN) = filenum;
if (host.developer >= D_WARN)
if(host.developer >= D_WARN)
Msg("VM_fopen: %s: %s mode %s opened as #%i\n", PRVM_NAME, filename, modestring, filenum);
}
}
@ -1473,7 +1499,7 @@ fclose(float fhandle)
=========
*/
//void(float fhandle) fclose = #111; // closes a file
void VM_fclose(void)
void VM_fclose( void )
{
int filenum;
@ -1490,10 +1516,12 @@ void VM_fclose(void)
VM_Warning("VM_fclose: no such file handle %i (or file has been closed) in %s\n", filenum, PRVM_NAME);
return;
}
FS_Close(prog->openfiles[filenum]);
FS_Close(VFS_Close(prog->openfiles[filenum]));
prog->openfiles[filenum] = NULL;
if (host.developer >= D_WARN)
{
Msg("VM_fclose: %s: #%i closed\n", PRVM_NAME, filenum);
}
}
/*
@ -1524,7 +1552,7 @@ void VM_fgets(void)
return;
}
c = FS_Gets (prog->openfiles[filenum], string, VM_STRINGTEMP_LENGTH );
c = VFS_Gets(prog->openfiles[filenum], string, VM_STRINGTEMP_LENGTH );
if (host.developer >= D_WARN) Msg("fgets: %s: %s\n", PRVM_NAME, string);
@ -1546,7 +1574,7 @@ void VM_fputs(void)
char string[VM_STRINGTEMP_LENGTH];
int filenum;
VM_SAFEPARMCOUNT(2,VM_fputs);
VM_SAFEPARMCOUNT(2, VM_fputs);
filenum = (int)PRVM_G_FLOAT(OFS_PARM0);
if (filenum < 0 || filenum >= PRVM_MAX_OPENFILES)
@ -1560,10 +1588,8 @@ void VM_fputs(void)
return;
}
VM_VarString(1, string, sizeof(string));
if ((stringlength = (int)strlen(string)))
FS_Write(prog->openfiles[filenum], string, stringlength);
if (host.developer >= D_WARN)
Msg("fputs: %s: %s\n", PRVM_NAME, string);
if ((stringlength = (int)strlen(string))) VFS_Write(prog->openfiles[filenum], string, stringlength);
if (host.developer >= D_WARN) Msg("fputs: %s: %s\n", PRVM_NAME, string);
}
/*
@ -1689,7 +1715,7 @@ void VM_allocstring(void)
char string[VM_STRINGTEMP_LENGTH];
size_t alloclen;
VM_SAFEPARMCOUNT(1,VM_strzone);
VM_SAFEPARMCOUNT(1, VM_allocstring);
VM_VarString(0, string, sizeof(string));
alloclen = strlen(string) + 1;
@ -1709,7 +1735,7 @@ void FreeString(string s)
*/
void VM_freestring(void)
{
VM_SAFEPARMCOUNT(1,VM_strunzone);
VM_SAFEPARMCOUNT(1, VM_freestring);
PRVM_FreeString(PRVM_G_INT(OFS_PARM0));
}
@ -1840,6 +1866,20 @@ void VM_clientcount(void)
PRVM_G_FLOAT(OFS_RETURN) = host.maxclients;
}
/*
=========
VM_clientstate
float clientstate()
=========
*/
void VM_clientstate(void)
{
VM_SAFEPARMCOUNT(0,VM_clientstate);
PRVM_G_FLOAT(OFS_RETURN) = cls.state;
}
/*
=========
VM_getmousepos
@ -1850,7 +1890,7 @@ vector getmousepos()
void VM_getmousepos(void)
{
VM_SAFEPARMCOUNT(0,VM_getmousepos);
VM_SAFEPARMCOUNT(0, VM_getmousepos);
PRVM_G_VECTOR(OFS_RETURN)[0] = mouse_x;
PRVM_G_VECTOR(OFS_RETURN)[1] = mouse_y;
@ -2177,6 +2217,38 @@ void VM_precache_pic(void)
re->RegisterPic((char *)s); //may return empty frame
}
/*
=========
VM_drawcharacter
float drawcharacter(vector position, float character, vector scale, vector rgb, float alpha, float flag)
=========
*/
void VM_drawcharacter(void)
{
float *pos, *rgb;
char character;
VM_SAFEPARMCOUNT(3, VM_drawcharacter);
character = (char)PRVM_G_FLOAT(OFS_PARM1);
if(character == 0)
{
PRVM_G_FLOAT(OFS_RETURN) = -1;
VM_Warning("VM_drawcharacter: %s passed null character !\n", PRVM_NAME);
return;
}
pos = PRVM_G_VECTOR(OFS_PARM0);
rgb = PRVM_G_VECTOR(OFS_PARM3);
if(pos[2]) Msg("VM_drawcharacter: z value from \"pos\" discarded\n" );
re->SetColor( GetRGBA(rgb[0], rgb[1], rgb[2], 1.0f));
SCR_DrawSmallChar( pos[0], pos[1], character );
re->SetColor( NULL );
PRVM_G_FLOAT(OFS_RETURN) = 1;
}
/*
=========
VM_drawstring
@ -2208,6 +2280,32 @@ void VM_drawstring(void)
SCR_DrawBigString( pos[0], pos[1], string, alpha );
PRVM_G_FLOAT(OFS_RETURN) = 1;
}
/*
=========
VM_getimagesize
vector getimagesize(string pic)
=========
*/
void VM_getimagesize(void)
{
const char *p;
int w, h;
VM_SAFEPARMCOUNT(1, VM_getimagesize);
p = PRVM_G_STRING(OFS_PARM0);
if(!p) PRVM_ERROR("VM_getimagepos: %s passed null picture name !", PRVM_NAME);
VM_CheckEmptyString(p);
re->DrawGetPicSize( &w, &h, (char *)p );
PRVM_G_VECTOR(OFS_RETURN)[0] = w;
PRVM_G_VECTOR(OFS_RETURN)[1] = h;
PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
}
/*
=========
VM_drawpic
@ -2269,6 +2367,68 @@ void VM_drawfill(void)
PRVM_G_FLOAT(OFS_RETURN) = 1;
}
/*
========================
VM_cin_open
float cin_open(string name, float bits)
========================
*/
void VM_cin_open( void )
{
const char *name;
int flags;
VM_SAFEPARMCOUNT( 2, VM_cin_open );
name = PRVM_G_STRING( OFS_PARM0 );
flags = (int)PRVM_G_FLOAT( OFS_PARM1 );
VM_CheckEmptyString( name );
if(SCR_PlayCinematic( (char *)name, flags ))
PRVM_G_FLOAT( OFS_RETURN ) = 1;
else PRVM_G_FLOAT( OFS_RETURN ) = 0;
}
/*
========================
VM_cin_close
void cin_close( void )
========================
*/
void VM_cin_close( void )
{
VM_SAFEPARMCOUNT( 0, VM_cin_close );
SCR_StopCinematic();
}
/*
========================
VM_cin_getstate
float cin_getstate(void)
========================
*/
void VM_cin_getstate( void )
{
VM_SAFEPARMCOUNT( 0, VM_cin_getstate );
PRVM_G_FLOAT( OFS_RETURN ) = SCR_GetCinematicState();
}
/*
========================
VM_cin_restart
void cin_restart(void)
========================
*/
void VM_cin_restart( void )
{
SCR_ResetCinematic();
}
/*
=========
VM_keynumtostring

View File

@ -201,6 +201,7 @@ void VM_objerror (void);
void VM_print (void);
void VM_bprint (void);
void VM_sprint (void);
void VM_centerprint(void);
void VM_normalize (void);
void VM_veclength (void);
void VM_vectoyaw (void);
@ -266,7 +267,7 @@ void VM_fgets(void);
void VM_fputs(void);
// used by M_WriteToFile
// should be only called from a builtin
file_t *VM_GetFileHandle( int index );
vfile_t *VM_GetFileHandle( int index );
void VM_strlen(void);
void VM_strcat(void);
@ -283,6 +284,7 @@ void VM_argv (void);
void VM_isserver(void);
void VM_clientcount(void);
void VM_clientstate(void);
void VM_getmousepos(void);
void VM_gettime(void);
void VM_loadfromdata(void);
@ -297,6 +299,7 @@ void VM_search_getfilename(void);
void VM_chr(void);
void VM_iscachedpic(void);
void VM_precache_pic(void);
void VM_drawcharacter(void);
void VM_drawstring(void);
void VM_drawpic(void);
void VM_drawfill(void);
@ -313,11 +316,9 @@ void VM_stringtokeynum (void);
void VM_cin_open( void );
void VM_cin_close( void );
void VM_cin_setstate( void );
void VM_cin_getstate( void );
void VM_cin_restart( void );
void VM_drawline (void);
void VM_R_PolygonBegin (void);
void VM_R_PolygonVertex (void);
void VM_R_PolygonEnd (void);

View File

@ -1295,15 +1295,16 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
}
prog->progs = (dprograms_t *)FS_LoadFile(va("vprogs/%s", filename ), &filesize);
if (prog->progs == NULL || filesize < (fs_offset_t)sizeof(dprograms_t))
PRVM_ERROR ("PRVM_LoadProgs: couldn't load %s for %s", filename, PRVM_NAME);
PRVM_ERROR("PRVM_LoadProgs: couldn't load %s for %s\n", filename, PRVM_NAME);
MsgDev(D_INFO, "%s programs occupy %iK.\n", PRVM_NAME, filesize/1024);
prog->filecrc = CRC_Block((unsigned char *)prog->progs, filesize);
// byte swap the header
for (i = 0; i < (int)sizeof(*prog->progs)/4; i++) ((int *)prog->progs)[i] = LittleLong(((int *)prog->progs)[i]);
switch( prog->progs->version )
{
case QPROGS_VERSION:
@ -1320,14 +1321,16 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
PRVM_ERROR ("%s: %s has wrong version number (%i should be %i)", PRVM_NAME, filename, prog->progs->version, VPROGS_VERSION);
break;
}
// try to recognize progs.dat by crc
switch(prog->progs->crc)
{
case PROG_CRC_SERVER:
break;
case 10020:
break;
default:
PRVM_ERROR ("%s: %s system vars have been modified, progdefs.h is out of date", PRVM_NAME, filename);
PRVM_ERROR("%s: %s system vars have been modified, progdefs.h is out of date", PRVM_NAME, filename);
break;
}
MsgDev(D_INFO, "Loading %s [CRC %d]\n", filename, prog->progs->crc );
@ -1341,8 +1344,8 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
prog->globals.gp = (float *)((byte *)prog->progs + prog->progs->ofs_globals);
// debug info
if (prog->progs->ofslinenums) prog->linenums = (int *)((byte *)prog->progs + prog->progs->ofslinenums);
if (prog->progs->ofs_types) prog->types = (type_t *)((byte *)prog->progs + prog->progs->ofs_types);
if(prog->progs->ofslinenums) prog->linenums = (int *)((byte *)prog->progs + prog->progs->ofslinenums);
if(prog->progs->ofs_types) prog->types = (type_t *)((byte *)prog->progs + prog->progs->ofs_types);
// decompress progs if needed
if (prog->progs->blockscompressed & COMP_STATEMENTS)
@ -1554,11 +1557,11 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
{
case OP_IF:
case OP_IFNOT:
if ((word) st->a >= prog->progs->numglobals || (word)st->b + i < 0 || (word)st->b + i >= prog->progs->numstatements)
if((word)st->a >= prog->progs->numglobals || (word)st->b + i < 0 || (word)st->b + i >= prog->progs->numstatements)
PRVM_ERROR("PRVM_LoadProgs: out of bounds IF/IFNOT (statement %d) in %s", i, PRVM_NAME);
break;
case OP_GOTO:
if (st->a + i < 0 || st->a + i >= prog->progs->numstatements)
if(st->a + i < 0 || st->a + i >= prog->progs->numstatements)
PRVM_ERROR("PRVM_LoadProgs: out of bounds GOTO (statement %d) in %s", i, PRVM_NAME);
break;
// global global global
@ -1596,7 +1599,7 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
case OP_LOAD_S:
case OP_LOAD_FNC:
case OP_LOAD_V:
if ((word) st->a >= prog->progs->numglobals || (word) st->b >= prog->progs->numglobals || (word)st->c >= prog->progs->numglobals)
if((word) st->a >= prog->progs->numglobals || (word) st->b >= prog->progs->numglobals || (word)st->c >= prog->progs->numglobals)
PRVM_ERROR("PRVM_LoadProgs: out of bounds global index (statement %d)", i);
break;
// global none global
@ -1605,7 +1608,7 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
case OP_NOT_S:
case OP_NOT_FNC:
case OP_NOT_ENT:
if ((word) st->a >= prog->progs->numglobals || (word) st->c >= prog->progs->numglobals)
if((word) st->a >= prog->progs->numglobals || (word) st->c >= prog->progs->numglobals)
PRVM_ERROR("PRVM_LoadProgs: out of bounds global index (statement %d) in %s", i, PRVM_NAME);
break;
// 2 globals
@ -1623,7 +1626,7 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
case OP_STOREP_V:
case OP_STORE_V:
if ((word) st->a >= prog->progs->numglobals || (word) st->b >= prog->progs->numglobals)
PRVM_ERROR("PRVM_LoadProgs: out of bounds global index (statement %d) in %s", i, PRVM_NAME);
Host_Error("PRVM_LoadProgs: out of bounds global index (statement %d) in %s", i, PRVM_NAME);
break;
// 1 global
case OP_CALL0:
@ -1638,7 +1641,7 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
case OP_DONE:
case OP_RETURN:
if ((word) st->a >= prog->progs->numglobals)
PRVM_ERROR("PRVM_LoadProgs: out of bounds global index (statement %d) in %s", i, PRVM_NAME);
Host_Error("PRVM_LoadProgs: out of bounds global index (statement %d) in %s", i, PRVM_NAME);
break;
default:
MsgDev(D_NOTE, "PRVM_LoadProgs: unknown opcode %d at statement %d in %s\n", st->op, i, PRVM_NAME);
@ -1655,18 +1658,13 @@ void PRVM_LoadProgs (const char *filename, int numedfunc, char **ed_func, int nu
// set flags & ddef_ts in prog
prog->flag = 0;
prog->pev = PRVM_ED_FindGlobal("pev");
if( PRVM_ED_FindGlobal("time") && PRVM_ED_FindGlobal("time")->type & ev_float )
prog->time = &PRVM_G_FLOAT(PRVM_ED_FindGlobal("time")->ofs);
if(PRVM_ED_FindField ("chain"))
prog->flag |= PRVM_FE_CHAIN;
if(PRVM_ED_FindField ("classname"))
prog->flag |= PRVM_FE_CLASSNAME;
if(PRVM_ED_FindField ("chain")) prog->flag |= PRVM_FE_CHAIN;
if(PRVM_ED_FindField ("classname")) prog->flag |= PRVM_FE_CLASSNAME;
if(PRVM_ED_FindField ("nextthink") && PRVM_ED_FindField ("frame") && PRVM_ED_FindField ("think") && prog->flag && prog->pev)
prog->flag |= PRVM_OP_STATE;
@ -1925,16 +1923,16 @@ VM_error
Abort the server with a game error
===============
*/
void VM_Error (const char *fmt, ...)
void VM_Error(const char *fmt, ...)
{
char msg[1024];
va_list argptr;
va_start (argptr,fmt);
va_start (argptr, fmt);
vsprintf (msg, fmt, argptr);
va_end (argptr);
Msg ("Prvm error: %s", msg);
Host_Error("Prvm error: %s", msg);
}
/*

View File

@ -298,6 +298,10 @@ SOURCE=.\system.c
# End Source File
# Begin Source File
SOURCE=.\ui_cmds.c
# End Source File
# Begin Source File
SOURCE=.\ui_main.c
# End Source File
# Begin Source File

View File

@ -61,6 +61,8 @@ typedef struct host_parm_s
host_redirect_t rd; // remote console
jmp_buf abortframe; // abort current frame
char finalmsg[MAX_STRING];// server shutdown final message
dword framecount; // global framecount
double realtime; // host realtime
float frametime; // frametime (default 0.1)
@ -121,6 +123,9 @@ void Host_DPrintf(int level, const char *fmt, ...);
void Host_DWarnf( const char *fmt, ...);
void Host_Error( const char *error, ... );
// host dlls managment
void Host_FreeRender( void );
// host cmds
void Host_Error_f( void );
@ -159,9 +164,9 @@ void CL_Drop (void);
void CL_Shutdown (void);
void CL_Frame (float time);
void SV_Init (void);
void SV_Shutdown (char *finalmsg, bool reconnect);
void SV_Frame (float time);
void SV_Init( void );
void SV_Shutdown( bool reconnect );
void SV_Frame( float time );
void SV_Transform( sv_edict_t *ed, vec3_t origin, vec3_t angles );
/*

View File

@ -512,19 +512,22 @@ void Host_Error( const char *error, ... )
vsprintf( hosterror1, error, argptr );
va_end( argptr );
if (host.framecount < 3 || host.state == HOST_SHUTDOWN)
if( host.framecount < 3 || host.state == HOST_SHUTDOWN )
Sys_Error ("%s", hosterror1 );
else Host_Printf("Host_Error: %s", hosterror1);
if(recursive)
{
Msg("Host_Error: recursive %s", hosterror2);
Sys_Error ("%s", hosterror1);
Msg("Host_RecursiveError: %s", hosterror2 );
Sys_Error ("%s", hosterror1 );
return; // don't multiple executes
}
recursive = true;
strncpy(hosterror2, hosterror1, sizeof(hosterror2));
SV_Shutdown (va("Server crashed: %s", hosterror1), false);
recursive = true;
sprintf( host.finalmsg, "Server crashed: %s\n", hosterror1 );
std.strncpy( host.finalmsg, "Server shutdown\n", MAX_STRING );
SV_Shutdown( false );
CL_Drop(); // drop clients
recursive = false;
@ -624,15 +627,19 @@ void Host_Main( void )
oldtime = host.realtime;
// main window message loop
while (host.type != HOST_OFFLINE)
while( host.type != HOST_OFFLINE )
{
oldtime = newtime;
newtime = Sys_DoubleTime();
time = newtime - oldtime;
Host_Frame( time ); // engine frame
// engine frame
Host_Frame( time );
}
// prepare host to normal shutdown
host.state = HOST_SHUTDOWN;
std.strncpy( host.finalmsg, "Server shutdown\n", MAX_STRING );
}
@ -643,7 +650,7 @@ Host_Shutdown
*/
void Host_Free( void )
{
SV_Shutdown("Server shutdown\n", false );
SV_Shutdown( false );
CL_Shutdown();
Host_FreeRender();
NET_Shutdown();

View File

@ -18,11 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <ctype.h>
#ifdef _WIN32
#include <io.h>
#endif
#include "client.h"
#include "qmenu.h"
#include "uimenu.h"
static int m_main_cursor;
@ -613,7 +609,7 @@ static void M_UnbindCommand (char *command)
}
}
static void M_FindKeysForCommand(char *command, int *twokeys)
void M_FindKeysForCommand(char *command, int *twokeys)
{
int count;
int j;
@ -3421,6 +3417,9 @@ void M_Init (void)
Cmd_AddCommand ("menu_options", M_Menu_Options_f, "opens main options menu");
Cmd_AddCommand ("menu_keys", M_Menu_Keys_f, "opens redefinition keys menu" );
Cmd_AddCommand ("menu_quit", M_Menu_Quit_f, "show quit dialog" );
Cmd_AddCommand ("menu_toggle", UI_ToggleMenu_f, "enable progs menu(test)" );
UI_Init();
}
@ -3434,6 +3433,7 @@ void M_Draw (void)
if (cls.key_dest != key_menu) return;
m_drawfunc();
UI_Draw();
// delay playing the enter sound until after the
// menu has been drawn, to avoid delay while

View File

@ -38,12 +38,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
typedef struct _tag_menuframework
{
int x, y;
int x, y;
int cursor;
int nitems;
int nslots;
void *items[64];
int nslots;
void *items[64];
const char *statusbar;
@ -116,6 +116,7 @@ bool Menu_SelectItem( menuframework_s *s );
void Menu_SetStatusBar( menuframework_s *s, const char *string );
void Menu_SlideItem( menuframework_s *s, int dir );
int Menu_TallySlots( menuframework_s *menu );
void M_FindKeysForCommand(char *command, int *keys);
void Menu_DrawString( int, int, const char * );
void Menu_DrawStringDark( int, int, const char * );

View File

@ -492,7 +492,8 @@ Kick everyone off, possibly in preparation for a new game
void SV_KillServer_f (void)
{
if(!svs.initialized) return;
SV_Shutdown("Server was killed.\n", false);
std.strncpy( host.finalmsg, "Server was killed\n", MAX_STRING );
SV_Shutdown( false );
NET_Config( false );// close network sockets
}

View File

@ -257,10 +257,11 @@ void SV_InitGame (void)
char i, idmaster[32];
edict_t *ent;
if (svs.initialized)
if( svs.initialized )
{
// cause any connected clients to reconnect
SV_Shutdown("Server restarted\n", true);
std.strncpy( host.finalmsg, "Server restarted\n", MAX_STRING );
SV_Shutdown( true );
}
else
{

View File

@ -1035,16 +1035,16 @@ Called when each game quits,
before Sys_Quit or Sys_Error
================
*/
void SV_Shutdown (char *finalmsg, bool reconnect)
void SV_Shutdown( bool reconnect )
{
// already freed
if(host.state == HOST_ERROR) return;
MsgDev(D_NOTE, "SV_Shutdown: %s\n", finalmsg );
if (svs.clients) SV_FinalMessage (finalmsg, reconnect);
MsgDev(D_NOTE, "SV_Shutdown: %s\n", host.finalmsg );
if (svs.clients) SV_FinalMessage( host.finalmsg, reconnect);
Master_Shutdown ();
SV_ShutdownGameProgs ();
Master_Shutdown();
SV_ShutdownGameProgs();
// free current level
if (sv.demofile) FS_Close (sv.demofile);

View File

@ -1467,7 +1467,6 @@ void SV_ShutdownGameProgs (void)
SV_VM_End();
if(!svs.gclients) return;
Mem_Free( svs.gclients );
svs.gclients = NULL;

View File

@ -110,7 +110,7 @@ void S_Init( void )
s_show = Cvar_Get ("s_show", "0", CVAR_CHEAT);
s_testsound = Cvar_Get ("s_testsound", "0", CVAR_CHEAT);
cv = Cvar_Get ("s_initsound", "1", 0);
cv = Cvar_Get("s_initsound", "1", 0);
if ( !cv->value ) return;
Cmd_AddCommand("play", S_Play_f, "playing a specified sound file" );

View File

@ -28,20 +28,34 @@ SYSTEM IO
===============================================================================
*/
void Sys_Error( const char *error, ... )
{
char syserror1[MAX_INPUTLINE];
char errorstring[MAX_INPUTLINE];
static bool recursive = false;
va_list argptr;
va_start( argptr, error );
vsprintf( syserror1, error, argptr );
std.vsprintf( errorstring, error, argptr );
va_end( argptr );
SV_Shutdown(va("Server fatal crashed: %s\n", syserror1), false);
CL_Shutdown();
host.state = HOST_ERROR; // lock shutdown state
// don't multiple executes
if( recursive )
{
// echo to system console and log
Sys_Print( va("Sys_RecursiveError: %s\n", errorstring ));
return;
}
std.error("%s", syserror1);
recursive = true;
// prepare host to close
sprintf( host.finalmsg, "Server fatal crashed: %s\n", errorstring );
host.state = HOST_ERROR; // lock shutdown state
Host_FreeRender();
std.error("%s", errorstring );
}
/*

427
engine/ui_cmds.c Normal file
View File

@ -0,0 +1,427 @@
//=======================================================================
// Copyright XashXT Group 2007 ©
// ui_cmds.c - ui menu builtins
//=======================================================================
#include "uimenu.h"
/*
=========
VM_M_precache_file
string precache_file(string)
=========
*/
void VM_M_precache_file (void)
{
// precache_file is only used to copy files with qcc, it does nothing
VM_SAFEPARMCOUNT(1, VM_precache_file);
PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
}
/*
=========
VM_M_preache_error
used instead of the other VM_precache_* functions in the builtin list
=========
*/
void VM_M_precache_error (void)
{
PRVM_ERROR("PF_Precache: Precache can only be done in spawn functions");
}
/*
=========
VM_M_precache_sound
string precache_sound (string sample)
=========
*/
void VM_M_precache_sound( void )
{
const char *s;
VM_SAFEPARMCOUNT(1, VM_precache_sound);
s = PRVM_G_STRING(OFS_PARM0);
PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
VM_CheckEmptyString( s );
if(!SV_SoundIndex( s ))
{
VM_Warning("VM_precache_sound: Failed to load %s for %s\n", s, PRVM_NAME);
return;
}
}
/*
=========
VM_M_setmousetarget
setmousetarget(float target)
=========
*/
void VM_M_setmousetarget(void)
{
VM_SAFEPARMCOUNT(1, VM_M_setmousetarget);
Msg("VM_M_setmousetarget: called\n" );
}
/*
=========
VM_M_getmousetarget
float getmousetarget
=========
*/
void VM_M_getmousetarget(void)
{
VM_SAFEPARMCOUNT(0, VM_M_getmousetarget);
PRVM_G_FLOAT(OFS_RETURN) = 1;
}
/*
=========
VM_M_setkeydest
setkeydest(float dest)
=========
*/
void VM_M_setkeydest(void)
{
VM_SAFEPARMCOUNT(1, VM_M_setkeydest);
switch((int)PRVM_G_FLOAT(OFS_PARM0))
{
case 0:
// key_game
cls.key_dest = key_game;
break;
case 2:
// key_menu
cls.key_dest = key_menu;
break;
case 1:
// key_message
// cls.key_dest = key_message
// break;
default:
PRVM_ERROR("VM_M_setkeydest: wrong destination %f !", PRVM_G_FLOAT(OFS_PARM0));
}
}
/*
=========
VM_M_getkeydest
float getkeydest
=========
*/
void VM_M_getkeydest(void)
{
VM_SAFEPARMCOUNT(0,VM_M_getkeydest);
// key_game = 0, key_message = 1, key_menu = 2, unknown = 3
switch(cls.key_dest)
{
case key_game:
PRVM_G_FLOAT(OFS_RETURN) = 0;
break;
case key_menu:
PRVM_G_FLOAT(OFS_RETURN) = 2;
break;
case key_message:
// not supported
// PRVM_G_FLOAT(OFS_RETURN) = 1;
// break;
default:
PRVM_G_FLOAT(OFS_RETURN) = 3;
}
}
/*
=========
VM_M_callfunction
callfunction(...,string function_name)
Extension: pass
=========
*/
mfunction_t *PRVM_ED_FindFunction (const char *name);
void VM_M_callfunction(void)
{
mfunction_t *func;
const char *s;
if(prog->argc == 0)
PRVM_ERROR("VM_M_callfunction: 1 parameter is required !");
s = PRVM_G_STRING(OFS_PARM0 + (prog->argc - 1));
if(!s)
PRVM_ERROR("VM_M_callfunction: null string !");
VM_CheckEmptyString(s);
func = PRVM_ED_FindFunction(s);
if(!func)
PRVM_ERROR("VM_M_callfunciton: function %s not found !", s);
else if (func->first_statement < 0)
{
// negative statements are built in functions
int builtinnumber = -func->first_statement;
prog->xfunction->builtinsprofile++;
if (builtinnumber < prog->numbuiltins && prog->builtins[builtinnumber])
prog->builtins[builtinnumber]();
else
PRVM_ERROR("No such builtin #%i in %s", builtinnumber, PRVM_NAME);
}
else if(func > 0)
{
prog->argc--;
PRVM_ExecuteProgram(func - prog->functions,"");
prog->argc++;
}
}
/*
=========
VM_M_isfunction
float isfunction(string function_name)
=========
*/
mfunction_t *PRVM_ED_FindFunction (const char *name);
void VM_M_isfunction(void)
{
mfunction_t *func;
const char *s;
VM_SAFEPARMCOUNT(1, VM_M_isfunction);
s = PRVM_G_STRING(OFS_PARM0);
if(!s)
PRVM_ERROR("VM_M_isfunction: null string !");
VM_CheckEmptyString(s);
func = PRVM_ED_FindFunction(s);
if(!func)
PRVM_G_FLOAT(OFS_RETURN) = false;
else
PRVM_G_FLOAT(OFS_RETURN) = true;
}
/*
=========
VM_M_writetofile
writetofile(float fhandle, entity ent)
=========
*/
void VM_M_writetofile(void)
{
edict_t *ent;
vfile_t *file;
VM_SAFEPARMCOUNT(2, VM_M_writetofile);
file = VM_GetFileHandle( (int)PRVM_G_FLOAT(OFS_PARM0) );
if( !file )
{
VM_Warning("VM_M_writetofile: invalid or closed file handle\n");
return;
}
ent = PRVM_G_EDICT(OFS_PARM1);
if(ent->priv.ed->free)
{
VM_Warning("VM_M_writetofile: %s: entity %i is free !\n", PRVM_NAME, PRVM_EDICT_NUM(OFS_PARM1));
return;
}
PRVM_ED_Write(file, ent);
}
/*
=========
VM_M_findkeysforcommand
string findkeysforcommand(string command)
the returned string is an altstring
=========
*/
void VM_M_findkeysforcommand(void)
{
const char *cmd;
char *ret;
int keys[2];
int i;
VM_SAFEPARMCOUNT(1, VM_M_findkeysforcommand);
cmd = PRVM_G_STRING(OFS_PARM0);
VM_CheckEmptyString(cmd);
(ret = VM_GetTempString())[0] = 0;
M_FindKeysForCommand((char *)cmd, keys);
for(i = 0; i < 2; i++) std.strncat(ret, va(" \'%i\'", keys[i]), VM_STRINGTEMP_LENGTH);
PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(ret);
}
prvm_builtin_t vm_m_builtins[] =
{
0, // to be consistent with the old vm
// common builtings (mostly)
VM_checkextension,
VM_error,
VM_objerror,
VM_print,
VM_bprint,
VM_sprint,
VM_centerprint,
VM_normalize,
VM_veclength,
VM_vectoyaw, // #10
VM_vectoangles,
VM_random_float,
VM_localcmd,
VM_cvar,
VM_cvar_set,
VM_print,
VM_ftoa,
VM_fabs,
VM_vtoa,
VM_etos, // 20
VM_atof,
VM_create,
VM_remove,
VM_find,
VM_findfloat,
VM_findchain,
VM_findchainfloat,
VM_M_precache_file,
VM_M_precache_sound,
VM_coredump, // 30
VM_traceon,
VM_traceoff,
VM_eprint,
VM_rint,
VM_floor,
VM_ceil,
VM_nextent,
VM_sin,
VM_cos,
VM_sqrt, // 40
VM_randomvec,
VM_registercvar,
VM_min,
VM_max,
VM_bound,
VM_pow,
VM_copyentity,
VM_fopen,
VM_fclose,
VM_fgets, // 50
VM_fputs,
VM_strlen,
VM_strcat,
VM_substring,
VM_atov,
VM_allocstring,
VM_freestring,
VM_tokenize,
VM_argv,
VM_isserver, // 60
VM_clientcount,
VM_clientstate,
VM_clientcmd,
VM_changelevel,
VM_localsound,
VM_getmousepos,
VM_gettime,
VM_loadfromdata,
VM_loadfromfile,
VM_modulo, // 70
VM_cvar_string,
VM_crash,
VM_stackdump, // 73
VM_search_begin,
VM_search_end,
VM_search_getsize,
VM_search_getfilename, // 77
VM_chr,
VM_itof,
VM_ftoe, // 80
VM_itof, // isString
VM_altstr_count,
VM_altstr_prepare,
VM_altstr_get,
VM_altstr_set,
VM_altstr_ins,
VM_findflags,
VM_findchainflags,
NULL, // 89
NULL, // 90
e10, // 100
e100, // 200
e100, // 300
e100, // 400
e10, // 410
e10, // 420
e10, // 430
e10, // 440
e10, // 450
// draw functions
VM_iscachedpic,
VM_precache_pic,
NULL,
VM_drawcharacter,
VM_drawstring,
VM_drawpic,
VM_drawfill,
NULL,
NULL,
VM_getimagesize, // 460
VM_cin_open,
VM_cin_close,
NULL,
VM_cin_getstate,
VM_cin_restart, // 465
NULL, // 466
NULL,
NULL,
NULL,
NULL, // 470
e10, // 480
e10, // 490
e10, // 500
e100, // 600
// menu functions
VM_M_setkeydest,
VM_M_getkeydest,
VM_M_setmousetarget,
VM_M_getmousetarget,
VM_M_callfunction,
VM_M_writetofile,
VM_M_isfunction,
NULL,
VM_keynumtostring,
VM_M_findkeysforcommand, // 610
NULL,
NULL,
VM_parseentitydata,
VM_stringtokeynum, // 614
};
const int vm_m_numbuiltins = sizeof(vm_m_builtins) / sizeof(prvm_builtin_t);

View File

@ -9,11 +9,11 @@
#define M_F_KEYDOWN "m_keydown"
#define M_F_KEYUP "m_keyup"
#define M_F_DRAW "m_draw"
// normal menu names (rest)
#define M_F_TOGGLE "m_toggle"
#define M_F_SHUTDOWN "m_shutdown"
static char *m_required_func[] = {
static char *m_required_func[] =
{
M_F_INIT,
M_F_KEYDOWN,
M_F_DRAW,
@ -21,69 +21,55 @@ M_F_TOGGLE,
M_F_SHUTDOWN,
};
#ifdef NG_MENU
static bool m_displayed;
#endif
static int m_numrequiredfunc = sizeof(m_required_func) / sizeof(char*);
static func_t m_draw, m_keydown;
static mfunction_t *m_keyup;
void MR_SetRouting (bool forceold);
void MP_Error(const char *format, ...)
void UI_Error(const char *format, ...)
{
static bool processingError = false;
char errorstring[MAX_INPUTLINE];
va_list argptr;
static bool processingError = false;
char errorstring[MAX_INPUTLINE];
va_list argptr;
va_start (argptr, format);
std.vsnprintf (errorstring, sizeof(errorstring), format, argptr);
va_end (argptr);
Msg( "Menu_Error: %s\n", errorstring );
va_start( argptr, format );
std.vsnprintf(errorstring, sizeof(errorstring), format, argptr);
va_end( argptr );
Host_Error( "Menu_Error: %s\n", errorstring );
if( !processingError ) {
if( !processingError )
{
processingError = true;
PRVM_Crash();
processingError = false;
} else {
Msg( "Menu_Error: Recursive call to MP_Error (from PRVM_Crash)!\n" );
}
else Host_Error( "Menu_RecursiveError: call to UI_Error (from PRVM_Crash)!\n" );
// fall back to the normal menu
// say it
Con_Print("Falling back to normal menu\n");
Msg("Falling back to normal menu\n");
cls.key_dest = key_game;
// init the normal menu now -> this will also correct the menu router pointers
MR_SetRouting (TRUE);
Host_AbortCurrentFrame();
}
void MP_KeyEvent (int key, char ascii, bool downevent)
void UI_KeyEvent(menuframework_s *m, int key)
{
PRVM_Begin;
PRVM_SetProg(PRVM_MENUPROG);
PRVM_SetProg( PRVM_MENUPROG );
// set time
*prog->time = cls.realtime;
// pass key
prog->globals.gp[OFS_PARM0] = (float) key;
prog->globals.gp[OFS_PARM1] = (float) ascii;
if (downevent)
PRVM_ExecuteProgram(m_keydown, M_F_KEYDOWN"(float key, float ascii) required\n");
else if (m_keyup)
PRVM_ExecuteProgram((func_t)(m_keyup - prog->functions), M_F_KEYUP"(float key, float ascii) required\n");
prog->globals.gp[OFS_PARM0] = (float)key;
prog->globals.gp[OFS_PARM1] = (string_t)PRVM_SetEngineString(Key_KeynumToString(key));
PRVM_ExecuteProgram(m_keydown, M_F_KEYDOWN"(menuframework_s *m, int key) required\n");
PRVM_End;
}
void MP_Draw (void)
void UI_Draw( void )
{
PRVM_Begin;
PRVM_SetProg(PRVM_MENUPROG);
@ -91,12 +77,11 @@ void MP_Draw (void)
// set time
*prog->time = cls.realtime;
PRVM_ExecuteProgram(m_draw,"");
PRVM_ExecuteProgram( m_draw, "" );
PRVM_End;
}
void MP_ToggleMenu_f (void)
void UI_ToggleMenu_f( void )
{
PRVM_Begin;
PRVM_SetProg(PRVM_MENUPROG);
@ -104,26 +89,17 @@ void MP_ToggleMenu_f (void)
// set time
*prog->time = cls.realtime;
#ifdef NG_MENU
m_displayed = !m_displayed;
if( m_displayed )
PRVM_ExecuteProgram((func_t) (PRVM_ED_FindFunction(M_F_DISPLAY) - prog->functions),"");
else
PRVM_ExecuteProgram((func_t) (PRVM_ED_FindFunction(M_F_HIDE) - prog->functions),"");
#else
PRVM_ExecuteProgram((func_t) (PRVM_ED_FindFunction(M_F_TOGGLE) - prog->functions),"");
#endif
PRVM_ExecuteProgram((func_t) (PRVM_ED_FindFunction(M_F_TOGGLE) - prog->functions), "" );
PRVM_End;
}
void MP_Shutdown (void)
void UI_Shutdown( void )
{
PRVM_Begin;
PRVM_SetProg(PRVM_MENUPROG);
// set time
*prog->time = cls.realtime;
//*prog->time = cls.realtime;
PRVM_ExecuteProgram((func_t) (PRVM_ED_FindFunction(M_F_SHUTDOWN) - prog->functions),"");
@ -136,39 +112,29 @@ void MP_Shutdown (void)
PRVM_End;
}
void MP_Fallback (void)
{
MP_Shutdown();
cls.key_dest = key_game;
// init the normal menu now -> this will also correct the menu router pointers
MR_SetRouting (TRUE);
}
void MP_Init (void)
void UI_Init( void )
{
PRVM_Begin;
PRVM_InitProg(PRVM_MENUPROG);
PRVM_InitProg( PRVM_MENUPROG );
prog->edictprivate_size = 0; // no private struct used
prog->name = M_NAME;
prog->num_edicts = 1;
prog->limit_edicts = M_MAX_EDICTS;
prog->extensionstring = vm_m_extensions;
prog->extensionstring = "";
prog->builtins = vm_m_builtins;
prog->numbuiltins = vm_m_numbuiltins;
prog->init_cmd = VM_M_Cmd_Init;
prog->reset_cmd = VM_M_Cmd_Reset;
prog->error_cmd = MP_Error;
prog->init_cmd = VM_Cmd_Init;
prog->reset_cmd = VM_Cmd_Reset;
prog->error_cmd = UI_Error;
// allocate the mempools
prog->progs_mempool = Mem_AllocPool( M_PROG_FILENAME );
PRVM_LoadProgs(M_PROG_FILENAME, m_numrequiredfunc, m_required_func, 0, NULL);
PRVM_LoadProgs( M_PROG_FILENAME, m_numrequiredfunc, m_required_func, 0, NULL);
// set m_draw and m_keydown
m_draw = (func_t) (PRVM_ED_FindFunction(M_F_DRAW) - prog->functions);
m_keydown = (func_t) (PRVM_ED_FindFunction(M_F_KEYDOWN) - prog->functions);
m_draw = (func_t)(PRVM_ED_FindFunction(M_F_DRAW) - prog->functions);
m_keydown = (func_t)(PRVM_ED_FindFunction(M_F_KEYDOWN) - prog->functions);
m_keyup = PRVM_ED_FindFunction(M_F_KEYUP);
// set time
@ -176,80 +142,5 @@ void MP_Init (void)
// call the prog init
PRVM_ExecuteProgram((func_t) (PRVM_ED_FindFunction(M_F_INIT) - prog->functions),"");
PRVM_End;
}
void MP_Restart(void)
{
MP_Init();
}
//============================================================================
// Menu router
void (*MR_KeyEvent) (int key, char ascii, bool downevent);
void (*MR_Draw) (void);
void (*MR_ToggleMenu_f) (void);
void (*MR_Shutdown) (void);
void MR_SetRouting(bool forceold)
{
static bool m_init = FALSE, mp_init = FALSE;
// if the menu prog isnt available or forceqmenu ist set, use the old menu
if(!FS_FileExists(M_PROG_FILENAME))
{
// set menu router function pointers
/*MR_KeyEvent = M_KeyEvent;
MR_Draw = M_Draw;
MR_ToggleMenu_f = M_ToggleMenu_f;
MR_Shutdown = M_Shutdown;
*/
// init
if(!m_init)
{
M_Init();
m_init = TRUE;
}
else M_Restart();
}
else
{
// set menu router function pointers
MR_KeyEvent = MP_KeyEvent;
MR_Draw = MP_Draw;
MR_ToggleMenu_f = MP_ToggleMenu_f;
MR_Shutdown = MP_Shutdown;
if(!mp_init)
{
MP_Init();
mp_init = TRUE;
}
else
MP_Restart();
}
}
void MR_Restart(void)
{
MR_Shutdown();
MR_SetRouting(FALSE);
}
void Call_MR_ToggleMenu_f(void)
{
if(MR_ToggleMenu_f)
MR_ToggleMenu_f();
}
void MR_Init_Commands(void)
{
Cmd_AddCommand("menu_restart",MR_Restart, "restart menu system (reloads menu.dat");
}
void MR_Init(void)
{
}

View File

@ -23,10 +23,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "engine.h"
#include "client.h"
#include "qmenu.h"
#include "progsvm.h"
#include "vm_cmds.h"
#define M_PROG_FILENAME "menu.dat"
#define M_PROG_FILENAME "uimenu.dat"
#define M_NAME "menu"
#define M_MAX_EDICTS (1 << 12) // should be enough for a menu
@ -57,4 +58,10 @@ enum m_state_e {
};
extern enum m_state_e m_state;
void UI_Init( void );
void UI_KeyEvent(menuframework_s *m, int key);
void UI_ToggleMenu_f( void );
void UI_Shutdown( void );
void UI_Draw( void );
#endif//UIMENU_H

View File

@ -368,7 +368,9 @@ destroy win32 console
void Con_DestroyConsole( void )
{
// last text message into console or log
MsgDev(D_ERROR, "Sys_FreeLibrary: Unloading launch.dll\n");
if(Sys.crash) MsgDev(D_ERROR, "Sys_FreeLibrary: Hold launch.dll for debugging\n" );
else MsgDev(D_ERROR, "Sys_FreeLibrary: Unloading launch.dll\n");
if(Sys.hooked_out)
{

View File

@ -2584,6 +2584,46 @@ fs_offset_t VFS_Tell (vfile_t* file)
return file->offset;
}
/*
====================
FS_Getc
Get the next character of a file
====================
*/
int VFS_Getc(vfile_t *file)
{
char c;
if(!VFS_Read (file, &c, 1))
return EOF;
return c;
}
int VFS_Gets(vfile_t* file, byte *string, size_t bufsize )
{
int c, end = 0;
while( 1 )
{
c = VFS_Getc( file );
if (c == '\r' || c == '\n' || c < 0)
break;
if (end < bufsize - 1) string[end++] = c;
}
string[end] = 0;
// remove \n following \r
if (c == '\r')
{
c = VFS_Getc( file );
if (c != '\n') VFS_Seek( file, -1, SEEK_CUR ); // rewind
}
MsgDev(D_INFO, "VFS_Gets: %s\n", string);
return c;
}
int VFS_Seek( vfile_t *file, fs_offset_t offset, int whence )
{
if (!file) return -1;

View File

@ -149,6 +149,7 @@ void Sys_GetStdAPI( void )
std.vfclose = VFS_Close; // free buffer or write dump
std.vfwrite = VFS_Write; // write into buffer
std.vfread = VFS_Read; // read from buffer
std.vfgets = VFS_Gets; // read text line
std.vfprint = VFS_Print; // write message
std.vfprintf = VFS_Printf; // write formatted message
std.vfseek = VFS_Seek; // fseek, can seek in packfiles too
@ -764,33 +765,35 @@ void Sys_Error(const char *error, ...)
}
long _stdcall Sys_ExecptionFilter( PEXCEPTION_POINTERS pExceptionInfo )
long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo )
{
// save config
Sys_Print("Engine crashed\n");
Sys.crash = true;
Sys.Free(); // prepare host to close
Sys_FreeLibrary( Sys.linked_dll );
if(Sys.developer >= D_MEMORY)
{
// show execption in native console too
Con_ShowConsole( true );
Msg("Sys_Crash: call %p at address %p\n", pInfo->ExceptionRecord->ExceptionCode, pInfo->ExceptionRecord->ExceptionAddress );
Sys_WaitForQuit();
}
Con_DestroyConsole();
if( Sys.oldFilter ) return Sys.oldFilter( pExceptionInfo );
#if 1
if( Sys.oldFilter )
return Sys.oldFilter( pInfo );
return EXCEPTION_CONTINUE_SEARCH;
#else
return EXCEPTION_CONTINUE_EXECUTION;
#endif
}
void Sys_Init( void )
{
HANDLE hStdout;
OSVERSIONINFO vinfo;
MEMORYSTATUS lpBuffer;
char dev_level[4];
lpBuffer.dwLength = sizeof(MEMORYSTATUS);
vinfo.dwOSVersionInfoSize = sizeof(vinfo);
//oldFilter = SetUnhandledExceptionFilter( Sys_ExecptionFilter );
Sys.oldFilter = SetUnhandledExceptionFilter( Sys_Crash );
GlobalMemoryStatus (&lpBuffer);
Sys.hInstance = (HINSTANCE)GetModuleHandle( NULL ); // get current hInstance first
@ -845,7 +848,8 @@ void Sys_Exit ( void )
Memory_Shutdown();
Con_DestroyConsole();
if( Sys.oldFilter ) // restore filter
// restore filter
if( Sys.oldFilter )
SetUnhandledExceptionFilter( Sys.oldFilter );
exit( Sys.error );
}
@ -948,8 +952,14 @@ bool Sys_FreeLibrary ( dll_info_t *dll )
{
if(!dll || !dll->link) // invalid desc or alredy freed
return false;
if(Sys.crash)
{
// we need to hold down all modules, while MSVC can find erorr
MsgDev(D_ERROR, "Sys_FreeLibrary: Hold %s for debugging\n", dll->name );
return false;
}
else MsgDev(D_ERROR, "Sys_FreeLibrary: Unloading %s\n", dll->name );
MsgDev(D_ERROR, "Sys_FreeLibrary: Unloading %s\n", dll->name );
FreeLibrary (dll->link);
dll->link = NULL;

View File

@ -44,6 +44,7 @@ typedef struct system_s
bool con_showcredits;
bool con_silentmode;
bool error;
bool crash;
byte *basepool;
byte *zonepool;
byte *imagepool;
@ -241,6 +242,7 @@ fs_offset_t VFS_Read(vfile_t* file, void* buffer, size_t buffersize);
int VFS_Print(vfile_t* file, const char *msg);
int VFS_Printf(vfile_t* file, const char* format, ...);
int VFS_Seek( vfile_t *file, fs_offset_t offset, int whence );
int VFS_Gets(vfile_t* file, byte *string, size_t bufsize );
bool VFS_Unpack( void* compbuf, size_t compsize, void **buf, size_t size );
fs_offset_t VFS_Tell (vfile_t* file);
file_t *VFS_Close( vfile_t *file );

View File

@ -90,6 +90,7 @@ virtual filesystem manager
#define VFS_Read std.vfread
#define VFS_Print std.vfprint
#define VFS_Printf std.vfprintf
#define VFS_Gets std.vfgets
#define VFS_Seek std.vfseek
#define VFS_Tell std.vftell
#define VFS_Close std.vfclose

View File

@ -596,6 +596,7 @@ typedef struct stdilib_api_s
file_t *(*vfclose)(vfile_t* file); // free buffer or write dump
long (*vfwrite)(vfile_t* file, const void* buf, size_t datasize); // write into buffer
long (*vfread)(vfile_t* file, void* buffer, size_t buffersize); // read from buffer
int (*vfgets)(vfile_t* file, byte *string, size_t bufsize ); // read text line
int (*vfprint)(vfile_t* file, const char *msg); // write message
int (*vfprintf)(vfile_t* file, const char* format, ...); // write formatted message
int (*vfseek)(vfile_t* file, fs_offset_t offset, int whence); // fseek, can seek in packfiles too