From c068f22329d5cc722622a2183bbb22eef2093df7 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 24 Aug 2026 11:16:07 +0200 Subject: initial import --- src/parsec_server/.cproject | 44 + src/parsec_server/.project | 27 + src/parsec_server/MasterServer.cpp | 95 + src/parsec_server/MasterServerItem.cpp | 214 ++ src/parsec_server/con_act_sv.cpp | 3681 ++++++++++++++++++++++++++ src/parsec_server/con_aux_sv.cpp | 236 ++ src/parsec_server/con_com_sv.cpp | 849 ++++++ src/parsec_server/con_ext_sv.cpp | 1193 +++++++++ src/parsec_server/con_info_sv.cpp | 2120 +++++++++++++++ src/parsec_server/con_int_sv.cpp | 402 +++ src/parsec_server/con_list_sv.cpp | 1253 +++++++++ src/parsec_server/con_load_sv.cpp | 735 +++++ src/parsec_server/con_main_sv.cpp | 1586 +++++++++++ src/parsec_server/con_std_sv.cpp | 159 ++ src/parsec_server/e_colldet_sv.cpp | 1251 +++++++++ src/parsec_server/e_connmanager.cpp | 819 ++++++ src/parsec_server/e_gameserver.cpp | 1013 +++++++ src/parsec_server/e_global_sv.cpp | 146 + src/parsec_server/e_packethandler.cpp | 1544 +++++++++++ src/parsec_server/e_simnetinput.cpp | 401 +++ src/parsec_server/e_simnetoutput.cpp | 1195 +++++++++ src/parsec_server/e_simplayerinfo.cpp | 315 +++ src/parsec_server/e_simulator.cpp | 844 ++++++ src/parsec_server/e_world.cpp | 2710 +++++++++++++++++++ src/parsec_server/g_main_sv.cpp | 1192 +++++++++ src/parsec_server/g_player.cpp | 843 ++++++ src/parsec_server/g_stgate_sv.cpp | 672 +++++ src/parsec_server/include/MasterServer.h | 32 + src/parsec_server/include/MasterServerItem.h | 53 + src/parsec_server/include/con_act_sv.h | 239 ++ src/parsec_server/include/con_aux_sv.h | 59 + src/parsec_server/include/con_com_sv.h | 71 + src/parsec_server/include/con_ext_sv.h | 91 + src/parsec_server/include/con_info_sv.h | 63 + src/parsec_server/include/con_int_sv.h | 59 + src/parsec_server/include/con_list_sv.h | 34 + src/parsec_server/include/con_load_sv.h | 16 + src/parsec_server/include/con_main_sv.h | 168 ++ src/parsec_server/include/con_std_sv.h | 120 + src/parsec_server/include/e_colldet.h | 75 + src/parsec_server/include/e_connmanager.h | 247 ++ src/parsec_server/include/e_defs.h | 45 + src/parsec_server/include/e_gameserver.h | 204 ++ src/parsec_server/include/e_global_sv.h | 97 + src/parsec_server/include/e_packethandler.h | 147 + src/parsec_server/include/e_simnetinput.h | 48 + src/parsec_server/include/e_simnetoutput.h | 361 +++ src/parsec_server/include/e_simplayerinfo.h | 67 + src/parsec_server/include/e_simulator.h | 286 ++ src/parsec_server/include/e_world.h | 295 +++ src/parsec_server/include/e_world_trans.h | 33 + src/parsec_server/include/g_main_sv.h | 275 ++ src/parsec_server/include/g_player.h | 148 ++ src/parsec_server/include/inp_defs_sv.h | 30 + src/parsec_server/include/inp_keybmap_sv.h | 559 ++++ src/parsec_server/include/inp_main_sv.h | 12 + src/parsec_server/include/net_game_sv.h | 30 + src/parsec_server/include/net_packetdriver.h | 138 + src/parsec_server/include/net_subh_sv.h | 128 + src/parsec_server/include/net_udpdriver.h | 120 + src/parsec_server/include/net_util_sv.h | 25 + src/parsec_server/include/sl_util_sv.h | 9 + src/parsec_server/include/sys_err_sv.h | 31 + src/parsec_server/include/sys_msg_sv.h | 29 + src/parsec_server/include/sys_refframe_sv.h | 29 + src/parsec_server/include/sys_util_sv.h | 18 + src/parsec_server/inp_main_sv.cpp | 117 + src/parsec_server/net_packetdriver.cpp | 755 ++++++ src/parsec_server/net_util_sv.cpp | 138 + src/parsec_server/nl_udpdriver.cpp | 528 ++++ src/parsec_server/sl_util_sv.cpp | 106 + src/parsec_server/sv_main.cpp | 92 + src/parsec_server/sys_err_sv.cpp | 185 ++ src/parsec_server/sys_msg_sv.cpp | 355 +++ src/parsec_server/sys_util_sv.cpp | 73 + 75 files changed, 32379 insertions(+) create mode 100644 src/parsec_server/.cproject create mode 100644 src/parsec_server/.project create mode 100644 src/parsec_server/MasterServer.cpp create mode 100644 src/parsec_server/MasterServerItem.cpp create mode 100755 src/parsec_server/con_act_sv.cpp create mode 100755 src/parsec_server/con_aux_sv.cpp create mode 100755 src/parsec_server/con_com_sv.cpp create mode 100755 src/parsec_server/con_ext_sv.cpp create mode 100755 src/parsec_server/con_info_sv.cpp create mode 100755 src/parsec_server/con_int_sv.cpp create mode 100755 src/parsec_server/con_list_sv.cpp create mode 100755 src/parsec_server/con_load_sv.cpp create mode 100755 src/parsec_server/con_main_sv.cpp create mode 100755 src/parsec_server/con_std_sv.cpp create mode 100755 src/parsec_server/e_colldet_sv.cpp create mode 100755 src/parsec_server/e_connmanager.cpp create mode 100755 src/parsec_server/e_gameserver.cpp create mode 100755 src/parsec_server/e_global_sv.cpp create mode 100755 src/parsec_server/e_packethandler.cpp create mode 100755 src/parsec_server/e_simnetinput.cpp create mode 100755 src/parsec_server/e_simnetoutput.cpp create mode 100755 src/parsec_server/e_simplayerinfo.cpp create mode 100755 src/parsec_server/e_simulator.cpp create mode 100755 src/parsec_server/e_world.cpp create mode 100755 src/parsec_server/g_main_sv.cpp create mode 100755 src/parsec_server/g_player.cpp create mode 100755 src/parsec_server/g_stgate_sv.cpp create mode 100644 src/parsec_server/include/MasterServer.h create mode 100644 src/parsec_server/include/MasterServerItem.h create mode 100644 src/parsec_server/include/con_act_sv.h create mode 100644 src/parsec_server/include/con_aux_sv.h create mode 100644 src/parsec_server/include/con_com_sv.h create mode 100644 src/parsec_server/include/con_ext_sv.h create mode 100644 src/parsec_server/include/con_info_sv.h create mode 100644 src/parsec_server/include/con_int_sv.h create mode 100644 src/parsec_server/include/con_list_sv.h create mode 100644 src/parsec_server/include/con_load_sv.h create mode 100644 src/parsec_server/include/con_main_sv.h create mode 100644 src/parsec_server/include/con_std_sv.h create mode 100755 src/parsec_server/include/e_colldet.h create mode 100755 src/parsec_server/include/e_connmanager.h create mode 100644 src/parsec_server/include/e_defs.h create mode 100755 src/parsec_server/include/e_gameserver.h create mode 100755 src/parsec_server/include/e_global_sv.h create mode 100755 src/parsec_server/include/e_packethandler.h create mode 100755 src/parsec_server/include/e_simnetinput.h create mode 100755 src/parsec_server/include/e_simnetoutput.h create mode 100755 src/parsec_server/include/e_simplayerinfo.h create mode 100755 src/parsec_server/include/e_simulator.h create mode 100755 src/parsec_server/include/e_world.h create mode 100755 src/parsec_server/include/e_world_trans.h create mode 100755 src/parsec_server/include/g_main_sv.h create mode 100755 src/parsec_server/include/g_player.h create mode 100644 src/parsec_server/include/inp_defs_sv.h create mode 100644 src/parsec_server/include/inp_keybmap_sv.h create mode 100644 src/parsec_server/include/inp_main_sv.h create mode 100644 src/parsec_server/include/net_game_sv.h create mode 100755 src/parsec_server/include/net_packetdriver.h create mode 100755 src/parsec_server/include/net_subh_sv.h create mode 100755 src/parsec_server/include/net_udpdriver.h create mode 100644 src/parsec_server/include/net_util_sv.h create mode 100644 src/parsec_server/include/sl_util_sv.h create mode 100644 src/parsec_server/include/sys_err_sv.h create mode 100644 src/parsec_server/include/sys_msg_sv.h create mode 100644 src/parsec_server/include/sys_refframe_sv.h create mode 100755 src/parsec_server/include/sys_util_sv.h create mode 100755 src/parsec_server/inp_main_sv.cpp create mode 100755 src/parsec_server/net_packetdriver.cpp create mode 100755 src/parsec_server/net_util_sv.cpp create mode 100755 src/parsec_server/nl_udpdriver.cpp create mode 100755 src/parsec_server/sl_util_sv.cpp create mode 100755 src/parsec_server/sv_main.cpp create mode 100755 src/parsec_server/sys_err_sv.cpp create mode 100755 src/parsec_server/sys_msg_sv.cpp create mode 100755 src/parsec_server/sys_util_sv.cpp (limited to 'src/parsec_server') diff --git a/src/parsec_server/.cproject b/src/parsec_server/.cproject new file mode 100644 index 0000000..ba443c4 --- /dev/null +++ b/src/parsec_server/.cproject @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/parsec_server/.project b/src/parsec_server/.project new file mode 100644 index 0000000..5f7fdd4 --- /dev/null +++ b/src/parsec_server/.project @@ -0,0 +1,27 @@ + + + OpenParsec_uberlinuxguy + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/src/parsec_server/MasterServer.cpp b/src/parsec_server/MasterServer.cpp new file mode 100644 index 0000000..41bef75 --- /dev/null +++ b/src/parsec_server/MasterServer.cpp @@ -0,0 +1,95 @@ +/* + * MasterServer.cpp + * + * Created on: Jan 2, 2013 + * Author: jasonw + */ +// C library +#include +#include +#include +#include +#include +#include + +// C library +#include +#include +#include +#include +#include +#include + +// compilation flags/debug support +#include "config.h" +#include "debug.h" + +// general definitions +#include "general.h" +#include "objstruc.h" + +// global externals +#include "globals.h" + +// subsystem headers +#include "net_defs.h" +//FIXME: ???? +#include "sys_refframe_sv.h" + +// UNP header +#include "net_wrap.h" + +// server defs +#include "e_defs.h" + +// net game header +#include "net_game_sv.h" + +// mathematics header +#include "utl_math.h" + +// local module header +#include "e_gameserver.h" + +// proprietary module headers +#include "con_arg.h" +#include "con_aux_sv.h" +#include "con_com_sv.h" +#include "con_main_sv.h" +#include "e_colldet.h" +#include "g_extra.h" +#include "inp_main_sv.h" +#include "net_csdf.h" +#include "net_limits.h" +#include "net_udpdriver.h" +#include "net_util.h" +#include "net_packetdriver.h" +#include "obj_clas.h" +//#include "e_stats.h" +#include "g_main_sv.h" +#include "e_connmanager.h" +#include "e_packethandler.h" +#include "e_simulator.h" +#include "e_simnetinput.h" +#include "e_simnetoutput.h" +#include "sys_refframe_sv.h" +#include "sys_util_sv.h" + +#include "gd_help.h" + +#include "MasterServer.h" + +MasterServer::MasterServer() { + // TODO Auto-generated constructor stub + +} + +MasterServer::MasterServer(E_GameServer* gameserver) { + + +} + +MasterServer::~MasterServer() { + // TODO Auto-generated destructor stub +} + diff --git a/src/parsec_server/MasterServerItem.cpp b/src/parsec_server/MasterServerItem.cpp new file mode 100644 index 0000000..445e590 --- /dev/null +++ b/src/parsec_server/MasterServerItem.cpp @@ -0,0 +1,214 @@ +/* + * MasterServerList.cpp + * + * Created on: Jan 2, 2013 + * Author: jasonw + */ +// C library +#include +#include +#include +#include +#include +#include + +// compilation flags/debug support +#include "config.h" +#include "debug.h" + +// general definitions +#include "general.h" +#include "objstruc.h" + +// global externals +#include "globals.h" + +// subsystem headers +#include "net_defs.h" +//FIXME: ???? +#include "sys_refframe_sv.h" + +// UNP header +#include "net_wrap.h" + +// server defs +#include "e_defs.h" + +// net game header +#include "net_game_sv.h" + +// mathematics header +#include "utl_math.h" + +// local module header +#include "e_gameserver.h" + +// proprietary module headers +#include "con_arg.h" +#include "con_aux_sv.h" +#include "con_com_sv.h" +#include "con_main_sv.h" +#include "e_colldet.h" +#include "g_extra.h" +#include "inp_main_sv.h" +#include "net_csdf.h" +#include "net_limits.h" +#include "net_udpdriver.h" +#include "net_util.h" +#include "net_packetdriver.h" +#include "obj_clas.h" +//#include "e_stats.h" +#include "g_main_sv.h" +#include "e_connmanager.h" +#include "e_packethandler.h" +#include "e_simulator.h" +#include "e_simnetinput.h" +#include "e_simnetoutput.h" +#include "sys_refframe_sv.h" +#include "sys_util_sv.h" + +#include "gd_help.h" + + +#include "MasterServerItem.h" + +MasterServerItem::MasterServerItem() { + // TODO Auto-generated constructor stub + +} +MasterServerItem::MasterServerItem(int SrvID, int CurrPlayers, int MaxPlayers, + int PMajor, int PMinor, char ServerName[MAX_SERVER_NAME + 1], + char OS[MAX_OSNAME_LEN + 1], node_t *node) { + + _SrvID = SrvID; + _CurrPlayers = CurrPlayers; + _MaxPlayers = MaxPlayers; + _PMajor = PMajor; + _PMinor = PMinor; + strncpy(_ServerName, ServerName, MAX_SERVER_NAME); + _ServerName[MAX_SERVER_NAME] = '\0'; + strncpy(_OS, OS, MAX_OSNAME_LEN); + _OS[MAX_OSNAME_LEN] = '\0'; + NODE_Copy(&_Node, node); + +} +MasterServerItem::~MasterServerItem() { + // TODO Auto-generated destructor stub +} + +bool MasterServerItem::update(int SrvID, int CurrPlayers, int MaxPlayers, + int PMajor, int PMinor, char ServerName[MAX_SERVER_NAME + 1], + char OS[MAX_OSNAME_LEN + 1], node_t *node) { + + _SrvID = SrvID; + _CurrPlayers = CurrPlayers; + _MaxPlayers = MaxPlayers; + _PMajor = PMajor; + _PMinor = PMinor; + SAFE_STR_DUPLICATE(_ServerName, ServerName, MAX_SERVER_NAME-1); + _ServerName[MAX_SERVER_NAME] = '\0'; + SAFE_STR_DUPLICATE(_OS, OS, MAX_OSNAME_LEN-1); + _OS[MAX_OSNAME_LEN] = '\0'; + NODE_Copy(&_Node, node); + + + return true; +} + +bool MasterServerItem::remove() { + + // set the SrvID to -1 to indicate it should be removed. + _SrvID = -1; + + return false; +} + +bool MasterServerItem::operator <(const MasterServerItem& msl) const { + + return false; +} + +bool MasterServerItem::operator ==(const MasterServerItem& msl) const { + + return false; +} + +bool MasterServerItem::operator !=(const MasterServerItem& msl) const { + + return false; +} + + + +bool MasterServerItem::isValid() const { + if(_SrvID > -1) { + return true; + } + return false; +} + +int MasterServerItem::GetSrvID() { + return _SrvID; +} + +int MasterServerItem::GetCurrPlayers() { + return _CurrPlayers; +} + +int MasterServerItem::GetMaxPlayers() { + return _MaxPlayers; +} + +int MasterServerItem::GetPMajor() { + return _PMajor; +} + +int MasterServerItem::GetPMinor() { + return _PMinor; +} + +int MasterServerItem::GetServerName(char *buffer, int buffer_sz) { + + int str_sz = strlen(_ServerName); + if(buffer_sz < str_sz + 1){ + return -1; + } + + strncpy(buffer, _ServerName, str_sz); + buffer[str_sz + 1] = '\0'; + + return 0; +} + +int MasterServerItem::GetOS(char *buffer, int buffer_sz) { + int str_sz = strlen(_OS); + if(buffer_sz < str_sz + 1){ + return -1; + } + + strncpy(buffer, _OS, str_sz); + buffer[str_sz + 1] = '\0'; + + return 0; +} + +MasterServerItem::MasterServerItem(const MasterServerItem& msi_copy) : + _SrvID (msi_copy._SrvID), + _CurrPlayers (msi_copy._CurrPlayers), + _MaxPlayers (msi_copy._MaxPlayers), + _PMajor (msi_copy._PMajor), + _PMinor (msi_copy._PMinor) +{ + strncpy(_ServerName, msi_copy._OS, MAX_SERVER_NAME); + _ServerName[MAX_SERVER_NAME]='\0'; + strncpy( _OS, msi_copy._OS, MAX_OSNAME_LEN); + _OS[MAX_OSNAME_LEN]='\0'; + memcpy(&_Node, &msi_copy._Node, sizeof( node_t )); + +} + +int MasterServerItem::GetNode(node_t* node) { + NODE_Copy(node, &_Node); + + return true; +} diff --git a/src/parsec_server/con_act_sv.cpp b/src/parsec_server/con_act_sv.cpp new file mode 100755 index 0000000..98de7b3 --- /dev/null +++ b/src/parsec_server/con_act_sv.cpp @@ -0,0 +1,3681 @@ +/* + * PARSEC - Server Action Commands + * + * $Author: uberlinuxguy $ - $Date: 2004/09/26 03:43:47 $ + * + * Orginally written by: + * Copyright (c) Clemens Beer 2002 + * Copyright (c) Markus Hadwiger 1997-2000 + * + * 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 2 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +// C library +#include +#include +#include +#include +#include + +// compilation flags/debug support +#include "config.h" +#include "debug.h" + +// general definitions +#include "general.h" +#include "objstruc.h" + +// global externals +#include "globals.h" +#include "e_world_trans.h" + +// subsystem headers +//#include "aud_defs.h" +//#include "inp_defs.h" +#include "net_defs.h" +#include "sys_defs.h" +//#include "vid_defs.h" + +// mathematics header +#include "utl_math.h" + +// local module header +#include "con_act_sv.h" + +// proprietary module headers +#include "con_aux_sv.h" +#include "con_ext_sv.h" +#include "con_int_sv.h" +#include "con_main_sv.h" +//#include "e_demo.h" +//#include "e_record.h" +//#include "e_replay.h" +//#include "e_supp.h" +//#include "g_camera.h" +//#include "g_supp.h" +//#include "h_drwhud.h" +//#include "h_supp.h" +//#include "h_text.h" +//#include "m_main.h" +//#include "net_game.h" +#ifdef LINKED_PROTOCOL_GAMESERVER +// #include "net_serv.h" +#endif // LINKED_PROTOCOL_GAMESERVER +#include "obj_clas.h" +//#include "obj_ctrl.h" +//#include "obj_xtra.h" +//#include "part_sfx.h" +//#include "part_wfx.h" +//#include "g_emp.h" +#include "sys_file.h" + + +// flags +#define REINIT_LOCAL_SHIP_ON_PREP_RESTORE +#define RECOVER_TARGET_ON_MISSILE_CREATION + + + +// generic string paste area -------------------------------------------------- +// +#define PASTE_STR_LEN 255 +static char paste_str[ PASTE_STR_LEN + 1 ]; + + +// string constants ----------------------------------------------------------- +// +static char invalid_key_id[] = "invalid key identifier."; +static char no_batch_open[] = "no script open."; +static char too_many_pseudos[] = "too many pseudo stars."; +static char no_objcam_allowed[] = "object camera must not be active."; +static char invalid_list[] = "invalid list identifier."; +static char invalid_class[] = "invalid object class identifier."; +static char invalid_action[] = "invalid action."; +static char invalid_id_range[] = "object class id out of range."; +static char no_action_found[] = "no action specified."; +static char non_batch_use[] = "only valid if called from command script."; +static char stream_name_inval[] = "stream name is invalid."; +static char no_stream_started[] = "stream could not be started."; +static char no_stream_stopped[] = "no stream has been stopped."; +static char action_preempted[] = "action command not allowed."; +static char compile_write_err[] = "write error during compilation."; +static char compile_arg_inval[] = "invalid argument found during compilation."; +static char compile_non_comp[] = "non-compilable command found during compilation."; +static char compile_pkt_inval[] = "packet not found during compilation."; +static char only_for_compile[] = "command is only for compilation."; +static char invalid_bin_wait[] = "invalid binary wait argument encountered."; +static char maxplayers_diff[] = "netplayers limit is different from recording."; + + +// pointer to binary parameters ----------------------------------------------- +// +static char *bin_params = NULL; + + +// swap array of int values --------------------------------------------------- +// +INLINE +void SwapParams_int( int num, int32 *source, int32 *dest ) +{ + +#ifdef SYSTEM_BIG_ENDIAN + + for ( int indx = 0; indx < num; indx++ ) { + dest[ indx ] = SWAP_32( source[ indx ] ); + } + +#else + + memcpy( dest, source, sizeof( int32 ) * num ); + +#endif + +} + + +// swap array of hprec_t values ----------------------------------------------- +// +INLINE +void SwapParams_hprec( int num, hprec_t *source, hprec_t *dest ) +{ + +#ifdef SYSTEM_BIG_ENDIAN + + for ( int indx = 0; indx < num; indx++ ) { + + dword *s = (dword *) &source[ indx ]; + dword *d = (dword *) &dest[ indx ]; + + d[ 0 ] = SWAP_32( s[ 1 ] ); + d[ 1 ] = SWAP_32( s[ 0 ] ); + } + +#else + + memcpy( dest, source, sizeof( hprec_t ) * num ); + +#endif + +} + + +// allow no arguments at all instead of all arguments (one-shot flag!!) ------- +// +static int silent_missing_args = FALSE; // all args missing allowed +static int silent_missing_ok; // args were missing, not invalid + + +// check single parameter for action command ---------------------------------- +// +PRIVATE +int AcFetchIntParams( int num, int32 *params ) +{ + ASSERT( num > 0 ); + ASSERT( params != NULL ); + + // assume incorrectly missing arg + silent_missing_ok = FALSE; + + // read parameters binary if possible + if ( bin_params != NULL ) { + SwapParams_int( num, (int32 *) bin_params, params ); + silent_missing_args = FALSE; + return TRUE; + } + + // read specified number of int parameters + while ( num-- ) { + + char *nextparam = strtok( NULL, " " ); + if ( nextparam == NULL ) { + if ( !silent_missing_args ) + CON_AddLine( arg_missing ); + silent_missing_ok = silent_missing_args; + silent_missing_args = FALSE; + return FALSE; + } + + // disabling after first argument enforces either no + // arguments at all, or the entire specified number + // of arguments have to be specified + silent_missing_args = FALSE; + + char *errpart; + int32 ival = (int32) strtol( nextparam, &errpart, int_calc_base ); + + if ( *errpart != 0 ) { + CON_AddLine( invalid_arg ); + return FALSE; + } + + *params++ = ival; + } + + // make sure flag is reset + ASSERT( !silent_missing_args ); + silent_missing_args = FALSE; + + if ( strtok( NULL, " " ) != NULL ) { + CON_AddLine( too_many_args ); + return FALSE; + } + + return TRUE; +} + + +// check float parameters for action command ---------------------------------- +// +PRIVATE +int AcFetchFloatParams( int num, hprec_t *params ) +{ + ASSERT( num > 0 ); + ASSERT( params != NULL ); + + // assume incorrectly missing arg + silent_missing_ok = TRUE; + + // read parameters binary if possible + if ( bin_params != NULL ) { + SwapParams_hprec( num, (hprec_t *) bin_params, params ); + silent_missing_args = FALSE; + return TRUE; + } + + // read specified number of high precision float parameters + while ( num-- ) { + + char *nextparam = strtok( NULL, " " ); + if ( nextparam == NULL ) { + if ( !silent_missing_args ) + CON_AddLine( arg_missing ); + silent_missing_ok = silent_missing_args; + silent_missing_args = FALSE; + return FALSE; + } + + // disabling after first argument enforces either no + // arguments at all, or the entire specified number + // of arguments have to be specified + silent_missing_args = FALSE; + + char *errpart; + hprec_t dval = strtod( nextparam, &errpart ); + + if ( *errpart != 0 ) { + CON_AddLine( invalid_arg ); + return FALSE; + } + + *params++ = dval; + } + + // make sure flag is reset + ASSERT( !silent_missing_args ); + silent_missing_args = FALSE; + + if ( strtok( NULL, " " ) != NULL ) { + CON_AddLine( too_many_args ); + return FALSE; + } + + return TRUE; +} + + +// check string parameter for action command ---------------------------------- +// +PRIVATE +int AcFetchStringParam( char **param, int stripspace ) +{ + ASSERT( param != NULL ); + + // no invalid args + silent_missing_ok = TRUE; + + // read parameter binary if possible + if ( bin_params != NULL ) { + *param = bin_params; + silent_missing_args = FALSE; + return TRUE; + } + + char *nextparam = strtok( NULL, "" ); + if ( nextparam != NULL ) { + + if ( stripspace ) { + + // eat whitespace + char *scan = nextparam; + while ( *scan == ' ' ) + scan++; + + // argument found? + if ( *scan != 0 ) { + + nextparam = scan; + + // cut off trailing whitespace + while ( *scan != 0 ) + scan++; + while ( *--scan == ' ' ) + {} + *( scan + 1 ) = 0; + + } else { + + if ( !silent_missing_args ) + CON_AddLine( arg_missing ); + nextparam = NULL; + } + } + + } else { + + if ( !silent_missing_args ) { + CON_AddLine( arg_missing ); + } + } + + // reset flag + silent_missing_args = FALSE; + + *param = nextparam; + return ( nextparam != NULL ); +} + + +// set automatic pitch (global variable) -------------------------------------- +// +PRIVATE +void AcAutoPitch() +{ + /*bams_t angle; + if ( AcFetchIntParams( 1, &angle ) ) { + AutomaticPitch = angle; + }*/ +} + + +// set automatic yaw (global variable) ---------------------------------------- +// +PRIVATE +void AcAutoYaw() +{ + /*bams_t angle; + if ( AcFetchIntParams( 1, &angle ) ) { + AutomaticYaw = angle; + }*/ +} + + +// set automatic roll (global variable) --------------------------------------- +// +PRIVATE +void AcAutoRoll() +{ + /*bams_t angle; + if ( AcFetchIntParams( 1, &angle ) ) { + AutomaticRoll = angle; + }*/ +} + + +// set automatic horizontal slide (global variable) --------------------------- +// +PRIVATE +void AcAutoSlideX() +{ + /*hprec_t slideval; + if ( AcFetchFloatParams( 1, &slideval ) ) { + AutomaticSlideHorz = FLOAT_TO_GEOMV( slideval ); + }*/ +} + + +// set automatic vertical slide (global variable) ----------------------------- +// +PRIVATE +void AcAutoSlideY() +{ + /*hprec_t slideval; + if ( AcFetchFloatParams( 1, &slideval ) ) { + AutomaticSlideVert = FLOAT_TO_GEOMV( slideval ); + }*/ +} + + +// set automatic movement (global variable and MyShip's speed) ---------------- +// +PRIVATE +void AcAutoMove() +{ + /*fixed_t translation; + if ( AcFetchIntParams( 1, &translation ) ) { + AutomaticMovement = translation; + MyShip->CurSpeed = AutomaticMovement; + }*/ +} + + +// set idle wait count -------------------------------------------------------- +// +PRIVATE +void AcIdleCommand() +{ + /*int32 waitcount; + if ( AcFetchIntParams( 1, &waitcount ) ) { + + // set duration to wait for + ASSERT( waitcount >= 0 ); + CurActionWait = waitcount; + + // remember for info + demoinfo_lastwait = (refframe_t) waitcount; + + // save level recursion is stalled on + idle_reclevel = rec_depth; + }*/ +} + + +// flag for view camera filter reset after matrix init ------------------------ +// +static int reset_viewcam_filter_on_update = FALSE; + + +// set single column of camera matrix ----------------------------------------- +// +INLINE +void SetCameraColumn( Camera cam, int col, hprec_t *v ) +{ + cam[ 0 ][ col ] = FLOAT_TO_GEOMV( v[ 0 ] ); + cam[ 1 ][ col ] = FLOAT_TO_GEOMV( v[ 1 ] ); + cam[ 2 ][ col ] = FLOAT_TO_GEOMV( v[ 2 ] ); +} + + +// set column #1 of camera matrix --------------------------------------------- +// +PRIVATE +void AcSetCamRotCol1() +{ + /*hprec_t v[ 3 ]; + if ( AcFetchFloatParams( 3, v ) ) { + SetCameraColumn( ShipViewCamera, 0, v ); + }*/ +} + + +// set column #2 of camera matrix --------------------------------------------- +// +PRIVATE +void AcSetCamRotCol2() +{ + /*hprec_t v[ 3 ]; + if ( AcFetchFloatParams( 3, v ) ) { + SetCameraColumn( ShipViewCamera, 1, v ); + }*/ +} + + +// set column #3 of camera matrix --------------------------------------------- +// +PRIVATE +void AcSetCamRotCol3() +{ + /*hprec_t v[ 3 ]; + if ( AcFetchFloatParams( 3, v ) ) { + SetCameraColumn( ShipViewCamera, 2, v ); + }*/ +} + + +// set column #4 of camera matrix --------------------------------------------- +// +PRIVATE +void AcSetCamOrigin() +{ + /*hprec_t v[ 3 ]; + if ( AcFetchFloatParams( 3, v ) ) { + SetCameraColumn( ShipViewCamera, 3, v ); + } + + // reset view camera smoothing filter if flag set + // (must be used if matrix is updated discontinuously) + if ( reset_viewcam_filter_on_update ) { + CAMERA_ResetFilter(); + reset_viewcam_filter_on_update = FALSE; + }*/ +} + + +// set single column of object position matrix -------------------------------- +// +PRIVATE +void SetObjectMatrxCol( int listid, int col, geomv_t x, geomv_t y, geomv_t z ) +{ + GenObject *obj = NULL; + + switch ( listid ) { + + case PSHIP_LIST_NO: + obj = (GenObject *) FetchFirstShip(); + break; + + case LASER_LIST_NO: + obj = (GenObject *) FetchFirstLaser(); + break; + + case MISSL_LIST_NO: + obj = (GenObject *) FetchFirstMissile(); + break; + + case EXTRA_LIST_NO: + obj = (GenObject *) FetchFirstExtra(); + break; + + case CUSTM_LIST_NO: + obj = (GenObject *) FetchFirstCustom(); + break; + } + + if ( obj != NULL ) { + obj->ObjPosition[ 0 ][ col ] = x; + obj->ObjPosition[ 1 ][ col ] = y; + obj->ObjPosition[ 2 ][ col ] = z; + } else { + CON_AddLine( invalid_list ); + } +} + + +// mapping table for class ids in demo to corresponding current ids ----------- +// +static dword class_map_id_to_name[ MAX_DISTINCT_OBJCLASSES ]; +static dword class_map_old_id; + + +// reset mapping table for class ids ------------------------------------------ +// +void ResetClassMapTable() +{ + // needed to preserve table across multiple + // demos that are played back-to-back + if ( SV_CLASS_MAP_TABLE_DISABLE_RESET ) + return; + + class_map_old_id = CLASS_ID_INVALID; + + for ( int cid = 0; cid < MAX_DISTINCT_OBJCLASSES; cid++ ) { + class_map_id_to_name[ cid ] = CLASS_ID_INVALID; + } +} + + +// set class id for which class name will be specified ------------------------ +// +void AcClassMapId() +{ + int32 classid; + if ( AcFetchIntParams( 1, &classid ) ) { + if ( (dword)classid < MAX_DISTINCT_OBJCLASSES ) { + class_map_old_id = classid; + } else { + class_map_old_id = CLASS_ID_INVALID; + } + } +} + + +// map class name to current id and set map to corresponding current id ------- +// +void AcClassMapName() +{ + char *classname; + if ( AcFetchStringParam( &classname, ACM_EAT_SPACE( ACM_CLASSMAPNAME ) ) ) { + + dword classid = OBJ_FetchObjectClassId( classname ); + if ( class_map_old_id != CLASS_ID_INVALID ) { + ASSERT( class_map_old_id < MAX_DISTINCT_OBJCLASSES ); + class_map_id_to_name[ class_map_old_id ] = classid; + } + } +} + + +// execute recorded object creation ------------------------------------------- +// +PRIVATE +GenObject *CreateRecordedObject( dword objclass, Xmatrx startmatrx ) +{ + ASSERT( startmatrx != NULL ); + + if ( objclass >= MAX_DISTINCT_OBJCLASSES ) { + CON_AddLine( invalid_id_range ); + return NULL; + } + + // map the recorded class id to the corresponding current class id + if ( class_map_id_to_name[ objclass ] != CLASS_ID_INVALID ) { + objclass = class_map_id_to_name[ objclass ]; + } + + // create object corresponding to original class +#ifdef PARSEC_SERVER + GenObject *obj = CreateObject( objclass, startmatrx, PLAYERID_SERVER ); +#else + GenObject *obj = CreateObject( objclass, startmatrx, LocalPlayerId ); +#endif // PARSEC_SERVER + if ( obj == NULL ) { + + CON_AddLine( invalid_class ); + + } else { + + // play sound effects for certain types + switch ( obj->ObjectType ) { + + case LASER1TYPE: + case LASER2TYPE: + case LASER3TYPE: + //AUD_Laser( obj ); + break; + + case MISSILE1TYPE: + case MISSILE4TYPE: + //AUD_Missile( obj ); + break; + + case MINE1TYPE: + //AUD_Mine( obj ); + break; + } + } + + return obj; +} + + +// for object creation on "ac.objmatrxcol4" instead of "ac.creatobject" ------- +// +static int delayed_object_creation = FALSE; +static dword delayed_object_class; +static dword delayed_object_id; +static dword delayed_object_hostid; +static Xmatrx delayed_object_matrix; + + +// execute delayed creation of recorded object -------------------------------- +// +INLINE +void DelayedObjectCreation() +{ + //NOTE: + // delayed object creation ensures that the objposition matrix + // is already valid on call of OBJ_CTRL::CreateObject(). + + // create object on setting of last matrix column + if ( delayed_object_creation ) { + delayed_object_creation = FALSE; + + GenObject *obj = + CreateRecordedObject( delayed_object_class, delayed_object_matrix ); + + if ( obj != NULL ) { +/* + if ( delayed_object_id != -1 ) { + obj->ObjectNumber = delayed_object_id; + } +*/ + if ( delayed_object_hostid != (dword)-1 ) { + obj->HostObjNumber = delayed_object_hostid; + } + } + } +} + + +// set single column of object position matrix -------------------------------- +// +INLINE +void SetObjMCol( int col ) +{ + hprec_t v[ 4 ]; + if ( AcFetchFloatParams( 4, v ) ) { + + if ( delayed_object_creation ) { + // remember for later use + delayed_object_matrix[ 0 ][ col ] = FLOAT_TO_GEOMV( v[ 1 ] ); + delayed_object_matrix[ 1 ][ col ] = FLOAT_TO_GEOMV( v[ 2 ] ); + delayed_object_matrix[ 2 ][ col ] = FLOAT_TO_GEOMV( v[ 3 ] ); + } else { + // set column directly in object structure + SetObjectMatrxCol( (int) v[ 0 ], col, + FLOAT_TO_GEOMV( v[ 1 ] ), + FLOAT_TO_GEOMV( v[ 2 ] ), + FLOAT_TO_GEOMV( v[ 3 ] ) ); + } + } +} + + +// set single column of object position matrix -------------------------------- +// +PRIVATE +void AcObjectMatrxColumn1() +{ + SetObjMCol( 0 ); +} + +PRIVATE +void AcObjectMatrxColumn2() +{ + SetObjMCol( 1 ); +} + +PRIVATE +void AcObjectMatrxColumn3() +{ + SetObjMCol( 2 ); +} + +PRIVATE +void AcObjectMatrxColumn4() +{ + SetObjMCol( 3 ); + DelayedObjectCreation(); +} + + +// set column #1 of fixed star matrix ----------------------------------------- +// +PRIVATE +void AcSetFixedStarRotCol1() +{ + // dummy for compatibility +} + + +// set column #2 of fixed star matrix ----------------------------------------- +// +PRIVATE +void AcSetFixedStarRotCol2() +{ + // dummy for compatibility +} + + +// set column #3 of fixed star matrix ----------------------------------------- +// +PRIVATE +void AcSetFixedStarRotCol3() +{ + // dummy for compatibility +} + + +// create object of specified class ------------------------------------------- +// +PRIVATE +void AcCreateObject() +{ + /*ASSERT( !delayed_object_creation ); + + int32 objclass; + if ( AcFetchIntParams( 1, &objclass ) ) { + + if ( AUX_NO_DELAYED_CREATE_OBJECT_REPLAY ) { + + // create on "ac.creatobject" + Xmatrx im; + MakeIdMatrx( im ); + CreateRecordedObject( objclass, im ); + + } else { + + // create later on "ac.objmatrxcol4" + delayed_object_creation = TRUE; + delayed_object_class = objclass; + delayed_object_id = -1; // not yet set + delayed_object_hostid = -1; // not yet set + } + }*/ +} + + +// delete all objects from specified object list ------------------------------ +// +PRIVATE +void AcDestroyObjectList() +{ + int32 listid; + if ( AcFetchIntParams( 1, &listid ) ) { + + switch ( listid ) { + + case PSHIP_LIST_NO: + FreeObjList( PShipObjects ); + break; + + case LASER_LIST_NO: + FreeObjList( LaserObjects ); + break; + + case MISSL_LIST_NO: + FreeObjList( MisslObjects ); + break; + + case EXTRA_LIST_NO: + FreeObjList( ExtraObjects ); + break; + + case CUSTM_LIST_NO: + FreeObjList( CustmObjects ); + break; + + default: + CON_AddLine( invalid_list ); + } + } +} + + +// write line 0 in small letters ---------------------------------------------- +// +PRIVATE +void AcWriteSmall() +{ + /*char *nextparam; + if ( AcFetchStringParam( &nextparam, ACM_EAT_SPACE( ACM_WRITESMALL ) ) ) { + HUD_SetDemoText( 0, nextparam ); + }*/ +} + + +// write line 1 in capital letters -------------------------------------------- +// +PRIVATE +void AcWriteBig() +{ + /*char *nextparam; + if ( AcFetchStringParam( &nextparam, ACM_EAT_SPACE( ACM_WRITEBIG1 ) ) ) { + HUD_SetDemoText( 1, nextparam ); + }*/ +} + + +// write line 2 in capital letters -------------------------------------------- +// +PRIVATE +void AcWriteBig2() +{ + /*char *nextparam; + if ( AcFetchStringParam( &nextparam, ACM_EAT_SPACE( ACM_WRITEBIG2 ) ) ) { + HUD_SetDemoText( 2, nextparam ); + }*/ +} + + +// write line 3 in capital letters -------------------------------------------- +// +PRIVATE +void AcWriteBig3() +{ + /*char *nextparam; + if ( AcFetchStringParam( &nextparam, ACM_EAT_SPACE( ACM_WRITEBIG3 ) ) ) { + HUD_SetDemoText( 3, nextparam ); + }*/ +} + + +// scroll demo text out ------------------------------------------------------- +// +PRIVATE +void AcClearText() +{ + //HUD_ClearDemoText(); +} + + +// set global maximum number of remote players (NET_GLOB::CurMaxPlayers) ------ +// +PRIVATE +void AcRemoteMaxPlayers() +{ + /*int32 maxnumplayers; + if ( AcFetchIntParams( 1, &maxnumplayers ) ) { + + if ( NetConnected == NETWORK_GAME_SIMULATED ) { + // simply set it + CurMaxPlayers = maxnumplayers; + } else { + // can't set it, display warning if different + if ( CurMaxPlayers != maxnumplayers ) { + CON_AddLine( maxplayers_diff ); + } + } + }*/ +} + + +// remember id of remote player whose state was set last ---------------------- +// +static int last_remote_playerid = 0; + + +// create remote player with specified state ---------------------------------- +// +PRIVATE +void AcRemotePlayer() +{ + /* + + //NOTE: + // if this is invoked specifying the local player, the + // local id may change. this has to happen in order to + // restore a consistent state with respect to the state + // during recording. the state of the local player will + // also be used to determine whether to activate or + // deactivate entry-mode automatically. + + int32 params[ 4 ]; + if ( AcFetchIntParams( 4, params ) ) { + + // remember id for AcRemoteMatrix(), AcRemoteName(), + // and AcRemoteWeaponsActive() + last_remote_playerid = params[ 0 ]; + + // init state except matrix and name + NET_SetRemotePlayerState( params[ 0 ], params[ 1 ], params[ 2 ], params[ 3 ] ); + } + + */ +} + + +// set remote player matrix --------------------------------------------------- +// +PRIVATE +void AcRemoteMatrix() +{ + /*if ( !NetConnected ) { + CON_AddLine( "AcRemoteMatrix(): no net." ); + return; + } + + hprec_t v[ 12 ]; + if ( AcFetchFloatParams( 12, v ) ) { + + Xmatrx matrix; + matrix[ 0 ][ 0 ] = FLOAT_TO_GEOMV( v[ 0 ] ); + matrix[ 0 ][ 1 ] = FLOAT_TO_GEOMV( v[ 1 ] ); + matrix[ 0 ][ 2 ] = FLOAT_TO_GEOMV( v[ 2 ] ); + matrix[ 0 ][ 3 ] = FLOAT_TO_GEOMV( v[ 3 ] ); + matrix[ 1 ][ 0 ] = FLOAT_TO_GEOMV( v[ 4 ] ); + matrix[ 1 ][ 1 ] = FLOAT_TO_GEOMV( v[ 5 ] ); + matrix[ 1 ][ 2 ] = FLOAT_TO_GEOMV( v[ 6 ] ); + matrix[ 1 ][ 3 ] = FLOAT_TO_GEOMV( v[ 7 ] ); + matrix[ 2 ][ 0 ] = FLOAT_TO_GEOMV( v[ 8 ] ); + matrix[ 2 ][ 1 ] = FLOAT_TO_GEOMV( v[ 9 ] ); + matrix[ 2 ][ 2 ] = FLOAT_TO_GEOMV( v[ 10 ] ); + matrix[ 2 ][ 3 ] = FLOAT_TO_GEOMV( v[ 11 ] ); + + // set matrix of remote player (using id set by AcRemotePlayer()) + NET_SetRemotePlayerMatrix( last_remote_playerid, matrix ); + + // for local player additionally set view camera + if ( Player_ShipId[ last_remote_playerid ] == SHIPID_LOCALPLAYER ) { + + ASSERT( LocalPlayerId == last_remote_playerid ); + ASSERT( Player_Ship[ last_remote_playerid ] == MyShip ); + + ObjCamOff(); + CalcOrthoInverse( MyShip->ObjPosition, DestXmatrx ); + memcpy( ShipViewCamera, DestXmatrx, sizeof( Camera ) ); + CAMERA_ResetFilter(); + } + }*/ +} + + +// set remote player weapons state -------------------------------------------- +// +PRIVATE +void AcRemoteWeaponsActive() +{ + /* + //NOTE: + // if new duration weapons are added this function + // should be updated. + + if ( !NetConnected ) { + CON_AddLine( "AcRemoteWeaponsActive(): no net." ); + return; + } + + int32 weaponsactive; + if ( AcFetchIntParams( 1, &weaponsactive ) ) { + + ASSERT( Player_Ship[ last_remote_playerid ] != NULL ); + ASSERT( Player_ShipId[ last_remote_playerid ] != SHIPID_LOCALPLAYER ); + + ShipObject *shippo = (ShipObject *) Player_Ship[ last_remote_playerid ]; + ASSERT( shippo != NULL ); + ASSERT( shippo != MyShip ); + + // check for lightning state change + dword oldstate = shippo->WeaponsActive & WPMASK_CANNON_LIGHTNING; + dword newstate = weaponsactive & WPMASK_CANNON_LIGHTNING; + if ( ( oldstate == 0 ) && ( newstate != 0 ) ) { + WFX_RemoteActivateLightning( last_remote_playerid ); + } else if ( ( oldstate != 0 ) && ( newstate == 0 ) ) { + WFX_RemoteDeactivateLightning( last_remote_playerid ); + } + + // check for helix state change + oldstate = shippo->WeaponsActive & WPMASK_CANNON_HELIX; + newstate = weaponsactive & WPMASK_CANNON_HELIX; + if ( ( oldstate == 0 ) && ( newstate != 0 ) ) { + WFX_RemoteActivateHelix( last_remote_playerid ); + } else if ( ( oldstate != 0 ) && ( newstate == 0 ) ) { + WFX_RemoteDeactivateHelix( last_remote_playerid ); + } + + // check for photon state change + oldstate = shippo->WeaponsActive & WPMASK_CANNON_PHOTON; + newstate = weaponsactive & WPMASK_CANNON_PHOTON; + if ( ( oldstate == 0 ) && ( newstate != 0 ) ) { + WFX_RemoteActivatePhoton( last_remote_playerid ); + } else if ( ( oldstate != 0 ) && ( newstate == 0 ) ) { + WFX_RemoteDeactivatePhoton( last_remote_playerid ); + } + + // check for emp state change + oldstate = shippo->WeaponsActive & WPMASK_DEVICE_EMP; + newstate = weaponsactive & WPMASK_DEVICE_EMP; + if ( ( oldstate == 0 ) && ( newstate != 0 ) ) { + WFX_RemoteActivateEmp( last_remote_playerid ); + } else if ( ( oldstate != 0 ) && ( newstate == 0 ) ) { + WFX_RemoteDeactivateEmp( last_remote_playerid ); + } + + // fallback for unknown duration weapons + // (simply set/reset activation bits) + dword unknownmask = 0xffffffff; + unknownmask &= ~WPMASK_CANNON_LIGHTNING; + unknownmask &= ~WPMASK_CANNON_HELIX; + unknownmask &= ~WPMASK_CANNON_PHOTON; + unknownmask &= ~WPMASK_DEVICE_EMP; + shippo->WeaponsActive &= ~unknownmask; + shippo->WeaponsActive |= weaponsactive & unknownmask; + } + */ +} + + +// should a join be performed on the next "ac.remotename" ? ------------------- +// +static int join_on_setname = FALSE; + + +// perform recorded join ------------------------------------------------------ +// +PRIVATE +void PerformRecordedJoin() +{ +/* if ( !NetJoined ) { + HideFloatingMenu(); + NETs_Join(); + EntryMode = FALSE; + InFloatingMenu = FALSE; + } + + ASSERT( EntryMode == FALSE ); + ASSERT( InFloatingMenu == FALSE ); +*/ +} + + +// set remote player name ----------------------------------------------------- +// +PRIVATE +void AcRemoteName() +{ + /*if ( !NetConnected ) { + CON_AddLine( "AcRemoteName(): no net." ); + return; + } + + char *nextparam; + if ( AcFetchStringParam( &nextparam, ACM_EAT_SPACE( ACM_REMOTENAME ) ) ) { + + // set name of remote player (using id set by AcRemotePlayer()) + NET_SetRemotePlayerName( last_remote_playerid, nextparam ); + } + + // perform delayed join + if ( join_on_setname ) { + join_on_setname = FALSE; + PerformRecordedJoin(); + }*/ +} + + +// perform join for local player ---------------------------------------------- +// +PRIVATE +void AcRemoteJoin() +{ + /*ASSERT( !join_on_setname ); + + int32 params[ 3 ]; + if ( AcFetchIntParams( 3, params ) ) { + + ASSERT( LocalPlayerId == params[ 0 ] ); + + //NOTE: + // player position has to be set by following "ac.remotematrix". + + // remember id for AcRemoteMatrix(), AcRemoteName(), + // and AcRemoteWeaponsActive() + last_remote_playerid = params[ 0 ]; + + // prepare local ship for join + InitJoinReplay(); + + if ( AUX_NO_DELAYED_JOIN_REPLAY ) { + PerformRecordedJoin(); + } else { + join_on_setname = TRUE; + } + }*/ +} + + +// perform unjoin for local player -------------------------------------------- +// +PRIVATE +void AcRemoteUnjoin() +{ + /*ASSERT( !join_on_setname ); + + if ( !NetConnected ) { + CON_AddLine( "AcRemoteUnjoin(): no net." ); + return; + } + + int32 params[ 3 ]; + if ( AcFetchIntParams( 3, params ) ) { + + ASSERT( LocalPlayerId == params[ 0 ] ); + + // set flags if not already unjoined + if ( NetJoined ) { + ExitGameLoop = 2; + if ( params[ 1 ] == SHIP_DOWNED ) { + ShipDowned = TRUE; + AUD_PlayerKilled(); + } else { + ShipDowned = FALSE; + } + } + }*/ +} + + +// clear remnants of demo replay ---------------------------------------------- +// +PRIVATE +void AcClearDemo() +{ +/* //NOTE: + // this function has to be used after a demo containing network packets + // has been replayed (and ended) to restore/ensure a proper game state. + + //NOTE: + // if the network mode is not active or the net simulation has already + // been stopped (e.g., the demo has finished) the network state will + // be left untouched (i.e., not reset!). + + ASSERT( !join_on_setname ); + + // specify optional argument flag + silent_missing_args = TRUE; + + // default is stop demo if running + int32 stopflag = 1; + AcFetchIntParams( 1, &stopflag ); + + //NOTE: + // ( silent_missing_ok == FALSE ) is alright here, since an error + // message will already have been displayed and we only wanted to + // override a default value anyway. + + // perform actual clear + DEMO_ClearDemo( stopflag ); +*/ +} + + +// start playback of recorded remote packet ----------------------------------- +// +PRIVATE +void AcPlayRemotePacket() +{ +/* int32 params[ 2 ]; + if ( AcFetchIntParams( 2, params ) ) { + + REC_PlayRemotePacket( params[ 0 ], params[ 1 ] ); + } +*/ +} + + +// replay recorded server message --------------------------------------------- +// +PRIVATE +void AcPlayServerMessage() +{ +/* char *nextparam; + if ( AcFetchStringParam( &nextparam, ACM_EAT_SPACE( ACM_SERVERMSG ) ) ) { + +#ifdef LINKED_PROTOCOL_GAMESERVER + if ( NET_ProtocolGMSV() ) { + NET_ServerParseMessage( nextparam ); + } else { + DBGTXT( MSGOUT( "AcPlayServerMessage(): in non GMSV mode !" ); ); + } +#endif // LINKED_PROTOCOL_GAMESERVER + + } +*/ +} + + +// display message in console ------------------------------------------------- +// +PRIVATE +void AcWriteConsoleText() +{ + /*char *msgtext; + if ( AcFetchStringParam( &msgtext, ACM_EAT_SPACE( ACM_WRITECONSOLETEXT ) ) ) { + + CON_AddLine( msgtext ); + }*/ +} + + +// display message in message area -------------------------------------------- +// +PRIVATE +void AcDisplayMessage() +{ + /*char *msgtext; + if ( AcFetchStringParam( &msgtext, ACM_EAT_SPACE( ACM_DISPLAYMESSAGE ) ) ) { + + ShowMessage( msgtext ); + }*/ +} + + +// execute a command supplied as string --------------------------------------- +// +PRIVATE +void AcExecCommandString() +{ + // make sure this is called from within a compiled demo + if ( bin_params == NULL ) { + CON_AddLine( "only valid during binary replay." ); + return; + } + + //NOTE: + // extreme care must be taken which commands are supplied to this + // function. right now, there are no safety checks for commands + // that must not be executed using this function. + + char *command; + if ( AcFetchStringParam( &command, ACM_EAT_SPACE( ACM_EXECCOMMAND ) ) ) { + + // command must belong to the class of non-compilable commands + ProcessExternalLine( command ); + ExecNonCompilableCommand( command ); + } +} + + +// macro to return with error message if recording inactive ------------------- +// +#define CHECK_RECORDING_STATE() \ +\ +if ( !RecordingActive ) { \ + CON_AddLine( no_batch_open ); \ + return; \ +} + + +// save all objects from specified object list -------------------------------- +// +PRIVATE +void AcSaveObjectList() +{ +/* CHECK_RECORDING_STATE(); + + // disallow object camera + if ( ObjCameraActive ) { + CON_AddLine( no_objcam_allowed ); + return; + } + + int32 listid; + if ( AcFetchIntParams( 1, &listid ) ) { + + switch ( listid ) { + + case PSHIP_LIST_NO: + Save_ObjListShips( RecordingFp ); + break; + + case LASER_LIST_NO: + Save_ObjListLasers( RecordingFp ); + break; + + case MISSL_LIST_NO: + Save_ObjListMissls( RecordingFp ); + break; + + case EXTRA_LIST_NO: + Save_ObjListExtras( RecordingFp ); + break; + + case CUSTM_LIST_NO: + Save_ObjListCustom( RecordingFp ); + break; + + default: + CON_AddLine( invalid_list ); + } + } +*/ +} + + +// save pseudo star positions ------------------------------------------------- +// +PRIVATE +void AcSavePseudoStars() +{ +/* + CHECK_RECORDING_STATE(); + Save_PseudoStars( RecordingFp ); +*/ +} + + +// save camera position and orientation --------------------------------------- +// +PRIVATE +void AcSaveCamera() +{ +/* + CHECK_RECORDING_STATE(); + Save_Camera( RecordingFp ); +*/ +} + + +// save fixed stars orientation ----------------------------------------------- +// +PRIVATE +void AcSaveFixedStars() +{ + // dummy for compatibility +} + + +// save state of all remote players ------------------------------------------- +// +PRIVATE +void AcSaveRemoteState() +{ +/* + CHECK_RECORDING_STATE(); + Save_RemoteState( RecordingFp ); +*/ +} + + +// kill all pseudo stars ------------------------------------------------------ +// +PRIVATE +void AcKillPseudoStars() +{ + //NumPseudoStars = 0; +} + + +// add single pseudo star ----------------------------------------------------- +// +PRIVATE +void AcAddPseudoStar() +{ + /*if ( NumPseudoStars < MAX_PSEUDO_STARS ) { + hprec_t pos[ 3 ]; + if ( AcFetchFloatParams( 3, pos ) ) { + int no = NumPseudoStars++; + PseudoStars[ no ].X = FLOAT_TO_GEOMV( pos[ 0 ] ); + PseudoStars[ no ].Y = FLOAT_TO_GEOMV( pos[ 1 ] ); + PseudoStars[ no ].Z = FLOAT_TO_GEOMV( pos[ 2 ] ); + } + } else { + CON_AddLine( too_many_pseudos ); + }*/ +} + + +// prepare restoration of data screen shot ------------------------------------ +// +PRIVATE +void AcPrepareDataRestore() +{ +/* + int shipclass = MyShip->ObjectClass; + + // allow optional specification of ship class + int32 sclass; + if ( AcFetchIntParams( 1, &sclass ) ) { + shipclass = sclass; + } + + // free objects and particles + KillAllObjects(); + + // delete pseudo stars + AcKillPseudoStars(); + +#ifdef REINIT_LOCAL_SHIP_ON_PREP_RESTORE + + // reinit local player's ship + InitLocalShipStatus( shipclass ); + InitHudDisplay(); + +#endif // REINIT_LOCAL_SHIP_ON_PREP_RESTORE + + // globally select shipclass + LocalShipClass = MyShip->ObjectClass; + + // set flag that view camera filter has to be reset + // after the new matrix has been set + reset_viewcam_filter_on_update = TRUE; + + // reset mapping table for class ids + ResetClassMapTable(); +*/ +} + + +// save data screen shot ------------------------------------------------------ +// +PRIVATE +void AcSaveDataInfo() +{ +/* + //NOTE: + // this function tries to create the logical analog to a screenshot. + // for this, it records the current state (that is, commands that + // are able to restore the current state on their execution). + + CHECK_RECORDING_STATE(); + Save_StateInfo( RecordingFp ); +*/ +} + + +// fade screen out (to black) ------------------------------------------------- +// +PRIVATE +void AcFadeOut() +{ +/* + +// VIDs_FadeScreenToBlack( PAL_GAME, FALSE ); + + int32 speed; + if ( AcFetchIntParams( 1, &speed ) ) { + + SetScreenFadeSpeed = speed; + + SetScreenFadeColor.R = 0; + SetScreenFadeColor.G = 0; + SetScreenFadeColor.B = 0; +// SetScreenFadeColor.A = irrelevant; + + // continue fading from current value + if ( SetScreenFade == 0 ) { + SetScreenFade = 0xff00; + } else if ( SetScreenFade < 0 ) { + SetScreenFade += 0xff00; + if ( SetScreenFade < 0 ) { + SetScreenFade = 0; + } + } + } +*/ +} + + +// fade screen in (from black) ------------------------------------------------ +// +PRIVATE +void AcFadeIn() +{ +/* +// VIDs_FadeScreenFromBlack( PAL_GAME ); + + int32 speed; + if ( AcFetchIntParams( 1, &speed ) ) { + + SetScreenFadeSpeed = speed; + + SetScreenFadeColor.R = 0; + SetScreenFadeColor.G = 0; + SetScreenFadeColor.B = 0; +// SetScreenFadeColor.A = irrelevant; + + // continue fading from current value + if ( ( SetScreenFade == 0 ) || ( SetScreenFade == 1 ) ) { + SetScreenFade = -0xff00; + } else if ( SetScreenFade > 0 ) { + SetScreenFade += -0xff00; + if ( SetScreenFade > 0 ) { + SetScreenFade = 0; + } + } + } +*/ +} + + +// fade screen out (to white) ------------------------------------------------- +// +PRIVATE +void AcWhiteFadeOut() +{ +/* +// colrgba_s scol = COLRGBA_WHITE; +// VIDs_SetScreenToColor( scol ); + + int32 speed; + if ( AcFetchIntParams( 1, &speed ) ) { + + SetScreenFadeSpeed = speed; + + SetScreenFadeColor.R = 255; + SetScreenFadeColor.G = 255; + SetScreenFadeColor.B = 255; +// SetScreenFadeColor.A = irrelevant; + + // continue fading from current value + if ( SetScreenFade == 0 ) { + SetScreenFade = 0xff00; + } else if ( SetScreenFade < 0 ) { + SetScreenFade += 0xff00; + if ( SetScreenFade < 0 ) { + SetScreenFade = 0; + } + } + } +*/ +} + + +// fade screen in (from white) ------------------------------------------------ +// +PRIVATE +void AcWhiteFadeIn() +{ +/* +// VIDs_FadeScreenFromWhite( PAL_GAME ); + + int32 speed; + if ( AcFetchIntParams( 1, &speed ) ) { + + SetScreenFadeSpeed = speed; + + SetScreenFadeColor.R = 255; + SetScreenFadeColor.G = 255; + SetScreenFadeColor.B = 255; +// SetScreenFadeColor.A = irrelevant; + + // continue fading from current value + if ( ( SetScreenFade == 0 ) || ( SetScreenFade == 1 ) ) { + SetScreenFade = -0xff00; + } else if ( SetScreenFade > 0 ) { + SetScreenFade += -0xff00; + if ( SetScreenFade > 0 ) { + SetScreenFade = 0; + } + } + } +*/ +} + + +// set standard palette ------------------------------------------------------- +// +PRIVATE +void AcStandardPalette() +{ +/* +// AwaitVertSync(); + + // turn off fading + SetScreenFade = 0; +*/ +} + + +// set entire palette to black ------------------------------------------------ +// +PRIVATE +void AcBlackScreen() +{ +/* +// colrgba_s scol = COLRGBA_BLACK; +// VIDs_SetScreenToColor( scol ); + + SetScreenFadeColor.R = 0; + SetScreenFadeColor.G = 0; + SetScreenFadeColor.B = 0; +// SetScreenFadeColor.A = irrelevant; + + // hold fading at opaque level + SetScreenFade = 1; +*/ +} + + +// set entire palette to white ------------------------------------------------ +// +PRIVATE +void AcWhiteScreen() +{ +/* +// colrgba_s scol = COLRGBA_WHITE; +// VIDs_SetScreenToColor( scol ); + + SetScreenFadeColor.R = 255; + SetScreenFadeColor.G = 255; + SetScreenFadeColor.B = 255; +// SetScreenFadeColor.A = irrelevant; + + // hold fading at opaque level + SetScreenFade = 1; +*/ +} + + +// set speed property of laser object ----------------------------------------- +// +PRIVATE +void AcSetLaserSpeed() +{ + fixed_t speed; + if ( AcFetchIntParams( 1, (int32 *) &speed ) ) { + LaserObject *scanpo = FetchFirstLaser(); + ASSERT( scanpo != NULL ); + scanpo->Speed = speed; + } +} + + +// set direction vector property of laser object ------------------------------ +// +PRIVATE +void AcSetLaserDirVec() +{ + hprec_t vec[ 3 ]; + if ( AcFetchFloatParams( 3, vec ) ) { + LaserObject *scanpo = FetchFirstLaser(); + ASSERT( scanpo != NULL ); + scanpo->DirectionVec.X = FLOAT_TO_GEOMV( vec[ 0 ] ); + scanpo->DirectionVec.Y = FLOAT_TO_GEOMV( vec[ 1 ] ); + scanpo->DirectionVec.Z = FLOAT_TO_GEOMV( vec[ 2 ] ); + } +} + + +// set owner property of laser object ----------------------------------------- +// +PRIVATE +void AcSetLaserOwner() +{ + int32 owner; + if ( AcFetchIntParams( 1, &owner ) ) { + LaserObject *scanpo = FetchFirstLaser(); + ASSERT( scanpo != NULL ); + scanpo->Owner = owner; + } +} + + +// set speed property of missile object --------------------------------------- +// +PRIVATE +void AcSetMisslSpeed() +{ + fixed_t speed; + if ( AcFetchIntParams( 1, (int32 *) &speed ) ) { + MissileObject *scanpo = FetchFirstMissile(); + ASSERT( scanpo != NULL ); + scanpo->Speed = speed; + } + +} + + +// set direction vector property of missile object ---------------------------- +// +PRIVATE +void AcSetMisslDirVec() +{ + hprec_t vec[ 3 ]; + if ( AcFetchFloatParams( 3, vec ) ) { + MissileObject *scanpo = FetchFirstMissile(); + ASSERT( scanpo != NULL ); + scanpo->DirectionVec.X = FLOAT_TO_GEOMV( vec[ 0 ] ); + scanpo->DirectionVec.Y = FLOAT_TO_GEOMV( vec[ 1 ] ); + scanpo->DirectionVec.Z = FLOAT_TO_GEOMV( vec[ 2 ] ); + } +} + + +// set owner property of missile object --------------------------------------- +// +PRIVATE +void AcSetMisslOwner() +{ + int32 owner; + if ( AcFetchIntParams( 1, &owner ) ) { + MissileObject *scanpo = FetchFirstMissile(); + ASSERT( scanpo != NULL ); + scanpo->Owner = owner; + } +} + + +// set target id property of missile object ----------------------------------- +// +PRIVATE +void AcSetMisslTarget() +{ +/* + //NOTE: + // this command will only occur to set the target + // of a guided missile fired by the local player. + + int32 target; + if ( AcFetchIntParams( 1, &target ) ) { + + TargetMissileObject *scanpo = (TargetMissileObject *) FetchFirstMissile(); + ASSERT( scanpo != NULL ); + ASSERT( ( scanpo->ObjectType & TYPECONTROLMASK ) == TYPEMISSILEISHOMING ); + scanpo->TargetObjNumber = target; + +#ifdef RECOVER_TARGET_ON_MISSILE_CREATION + + if ( TargetObjNumber != target ) { + + // set selected target to ensure the current + // selection is not wrong due to a lost keypress + TargetObjNumber = target; + CON_AddLine( "recovering target." ); + } +#endif + + } +*/ +} + + +// set owner property of mine object ------------------------------------------ +// +PRIVATE +void AcSetMineOwner() +{ +/* + int32 owner; + if ( AcFetchIntParams( 1, &owner ) ) { + MineObject *scanpo = (MineObject *) FetchFirstExtra(); + ASSERT( scanpo != NULL ); + scanpo->Owner = owner; + } +*/ +} + + +// create an extra ------------------------------------------------------------ +// +PRIVATE +void AcCreateExtra() +{ +/* + ASSERT( !delayed_object_creation ); + + int32 objclass; + if ( AcFetchIntParams( 1, &objclass ) ) { + + if ( (dword)objclass >= MAX_DISTINCT_OBJCLASSES ) { + CON_AddLine( invalid_id_range ); + return; + } + + // map the recorded class id to the corresponding current class id + if ( class_map_id_to_name[ objclass ] != CLASS_ID_INVALID ) { + objclass = class_map_id_to_name[ objclass ]; + } + + // create extra corresponding to original class + Xmatrx im; + MakeIdMatrx( im ); + ExtraObject *extrapo = (ExtraObject *) CreateObject( objclass, im ); + if ( extrapo == NULL ) { + CON_AddLine( invalid_class ); + } else { + OBJ_FillExtraMemberVars( extrapo ); + } + } +*/ +} + + +// create an energy field ----------------------------------------------------- +// +PRIVATE +void AcEnergyField() +{ +/* + hprec_t vec[ 3 ]; + if ( AcFetchFloatParams( 3, vec ) ) { + Vertex3 origin; + origin.X = FLOAT_TO_GEOMV( vec[ 0 ] ); + origin.Y = FLOAT_TO_GEOMV( vec[ 1 ] ); + origin.Z = FLOAT_TO_GEOMV( vec[ 2 ] ); + SFX_CreateEnergyField( origin ); + } +*/ +} + + +// shoot spreadfire gun ------------------------------------------------------- +// +PRIVATE +void AcSpreadfire() +{ +/* + WFX_ShootParticleWeapon( MyShip, PARTICLEGUN_SPREADFIRE ); +*/ +} + + +// activate lightning --------------------------------------------------------- +// +PRIVATE +void AcLightningOn() +{ +/* + if ( ( MyShip->WeaponsActive & WPMASK_CANNON_LIGHTNING ) == 0 ) { + WFX_ActivateLightning( MyShip ); + } else { + CON_AddLine( "filtering redundant lightning activation." ); + } +*/ +} + + +// deactivate lightning ------------------------------------------------------- +// +PRIVATE +void AcLightningOff() +{ +/* + if ( ( MyShip->WeaponsActive & WPMASK_CANNON_LIGHTNING ) != 0 ) { + WFX_DeactivateLightning( MyShip ); + } else { + CON_AddLine( "filtering redundant lightning deactivation." ); + } +*/ +} + + +// activate helix ------------------------------------------------------------- +// +void AcHelixOn() +{ +/* + if ( ( MyShip->WeaponsActive & WPMASK_CANNON_HELIX ) == 0 ) { + WFX_ActivateHelix( MyShip ); + } else { + CON_AddLine( "filtering redundant helix activation." ); + } +*/ +} + + +// deactivate helix ----------------------------------------------------------- +// +void AcHelixOff() +{ +/* + if ( ( MyShip->WeaponsActive & WPMASK_CANNON_HELIX ) != 0 ) { + WFX_DeactivateHelix( MyShip ); + } else { + CON_AddLine( "filtering redundant helix deactivation." ); + } +*/ +} + + +// activate photon ------------------------------------------------------------ +// +void AcPhotonOn() +{ +/* + if ( ( MyShip->WeaponsActive & WPMASK_CANNON_PHOTON ) == 0 ) { + WFX_ActivatePhoton( MyShip ); + } else { + CON_AddLine( "filtering redundant photon activation." ); + } +*/ +} + + +// deactivate photon ---------------------------------------------------------- +// +void AcPhotonOff() +{ +/* + if ( ( MyShip->WeaponsActive & WPMASK_CANNON_PHOTON ) != 0 ) { + WFX_DeactivatePhoton( MyShip ); + } else { + CON_AddLine( "filtering redundant photon deactivation." ); + } +*/ +} + + +// activate emp --------------------------------------------------------------- +// +void AcEmpOn() +{ +/* + if ( ( MyShip->WeaponsActive & WPMASK_DEVICE_EMP ) == 0 ) { + WFX_ActivateEmp( MyShip ); + } else { + CON_AddLine( "filtering redundant emp activation." ); + } +*/ +} + + +// deactivate emp ------------------------------------------------------------- +// +void AcEmpOff() +{ +/* + if ( ( MyShip->WeaponsActive & WPMASK_DEVICE_EMP) != 0 ) { + WFX_DeactivateEmp( MyShip ); + } else { + CON_AddLine( "filtering redundant emp deactivation." ); + } +*/ +} + + +// fire emp ------------------------------------------------------------------- +// +void AcEmp() +{ +/* + WFX_EmpBlast( MyShip ); +*/ +} + + +// set id of ship object that is first in list to specific value -------------- +// +PRIVATE +void AcSetObjectId() +{ +/* + int32 objid; + if ( AcFetchIntParams( 1, &objid ) ) { + if ( delayed_object_creation ) { + delayed_object_id = objid; + } else { + ShipObject *scanpo = FetchFirstShip(); + // ship must have been created previously + ASSERT( scanpo != NULL ); + if ( scanpo != NULL ) { + scanpo->ObjectNumber = objid; + } + } + } +*/ +} + + +// set host id of object to specific value to enable targeting for missiles --- +// +PRIVATE +void AcSetObjectHostId() +{ +/* + int32 objid; + if ( AcFetchIntParams( 1, &objid ) ) { + if ( delayed_object_creation ) { + delayed_object_hostid = objid; + } else { + ShipObject *scanpo = FetchFirstShip(); + // ship must have been created previously + ASSERT( scanpo != NULL ); + if ( scanpo != NULL ) { + scanpo->HostObjNumber = objid; + } + } + } +*/ +} + + +// simulate depression of single key ------------------------------------------ +// +PRIVATE +void AcSimulateKeyPress() +{ +/* int32 keynum; + if ( AcFetchIntParams( 1, &keynum ) ) { + if ( keynum < sizeof( keyfunc_s ) ) { + + ASSERT( sizeof( DepressedKeys->key_Escape ) == sizeof( byte ) ); + ((byte*)DepressedKeys)[ keynum ] = 1; + ((byte*)key_replay_map)[ keynum ] = 1; + + // explicitly check for object camera toggling + if ( offsetof( keyfunc_s, key_ToggleObjCamera ) == keynum ) { + ReplayObjCamActive = !ReplayObjCamActive; + } + + } else { + CON_AddLine( invalid_key_id ); + } + } +*/ +} + + +// simulate release of single key --------------------------------------------- +// +PRIVATE +void AcSimulateKeyRelease() +{ +/* + int32 keynum; + if ( AcFetchIntParams( 1, &keynum ) ) { + if ( keynum < sizeof( keyfunc_s ) ) { + ASSERT( sizeof( DepressedKeys->key_Escape ) == sizeof( byte ) ); + ((byte*)DepressedKeys)[ keynum ] = 0; + ((byte*)key_replay_map)[ keynum ] = 0; + } else { + CON_AddLine( invalid_key_id ); + } + } +*/ +} + + +// ---------------------------------------------------------------------------- +// local ship configuration commands - +// ---------------------------------------------------------------------------- + + +// current damage ------------------------------------------------------------- +// +PRIVATE +void AcMyShip_CurDamage() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->CurDamage = ivalue; + } +*/ +} + + +// maximum damage ------------------------------------------------------------- +// +PRIVATE +void AcMyShip_MaxDamage() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->MaxDamage = ivalue; + } +*/ +} + + +// current energy ------------------------------------------------------------- +// +PRIVATE +void AcMyShip_CurEnergy() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->CurEnergy = ivalue; + } +*/ +} + + +// maximum energy ------------------------------------------------------------- +// +PRIVATE +void AcMyShip_MaxEnergy() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->MaxEnergy = ivalue; + } +*/ +} + + +// current speed -------------------------------------------------------------- +// +PRIVATE +void AcMyShip_CurSpeed() +{ +/* + fixed_t ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->CurSpeed = ivalue; + } +*/ +} + + +// maximum speed -------------------------------------------------------------- +// +PRIVATE +void AcMyShip_MaxSpeed() +{ +/* + fixed_t ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->MaxSpeed = ivalue; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_NumMissls() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->NumMissls = ivalue; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_MaxNumMissls() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->MaxNumMissls = ivalue; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_NumHomMissls() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->NumHomMissls = ivalue; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_MaxNumHomMissls() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->MaxNumHomMissls = ivalue; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_NumPartMissls() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->NumPartMissls = ivalue; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_MaxNumPartMissls() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->MaxNumPartMissls = ivalue; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_NumMines() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->NumMines = ivalue; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_MaxNumMines() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->MaxNumMines = ivalue; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_Weapons() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->Weapons = ivalue; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_WeaponsActive() +{ +/* + //NOTE: + // if new duration weapons are added this function + // should be updated. + + int32 weaponsactive; + if ( AcFetchIntParams( 1, &weaponsactive ) ) { + + // check for lightning state change + dword oldstate = MyShip->WeaponsActive & WPMASK_CANNON_LIGHTNING; + dword newstate = weaponsactive & WPMASK_CANNON_LIGHTNING; + if ( ( oldstate == 0 ) && ( newstate != 0 ) ) { + WFX_ActivateLightning( MyShip ); + } else if ( ( oldstate != 0 ) && ( newstate == 0 ) ) { + WFX_DeactivateLightning( MyShip ); + } + + // check for helix state change + oldstate = MyShip->WeaponsActive & WPMASK_CANNON_HELIX; + newstate = weaponsactive & WPMASK_CANNON_HELIX; + if ( ( oldstate == 0 ) && ( newstate != 0 ) ) { + WFX_ActivateHelix( MyShip ); + } else if ( ( oldstate != 0 ) && ( newstate == 0 ) ) { + WFX_DeactivateHelix( MyShip ); + } + + // check for photon state change + oldstate = MyShip->WeaponsActive & WPMASK_CANNON_PHOTON; + newstate = weaponsactive & WPMASK_CANNON_PHOTON; + if ( ( oldstate == 0 ) && ( newstate != 0 ) ) { + WFX_ActivatePhoton( MyShip ); + } else if ( ( oldstate != 0 ) && ( newstate == 0 ) ) { + WFX_DeactivatePhoton( MyShip ); + } + + // check for emp state change + oldstate = MyShip->WeaponsActive & WPMASK_DEVICE_EMP; + newstate = weaponsactive & WPMASK_DEVICE_EMP; + if ( ( oldstate == 0 ) && ( newstate != 0 ) ) { + WFX_ActivateEmp( MyShip ); + } else if ( ( oldstate != 0 ) && ( newstate == 0 ) ) { + WFX_DeactivateEmp( MyShip ); + } + + // fallback for unknown duration weapons + // (simply set/reset activation bits) + dword unknownmask = 0xffffffff; + unknownmask &= ~WPMASK_CANNON_LIGHTNING; + unknownmask &= ~WPMASK_CANNON_HELIX; + unknownmask &= ~WPMASK_CANNON_PHOTON; + unknownmask &= ~WPMASK_DEVICE_EMP; + MyShip->WeaponsActive &= ~unknownmask; + MyShip->WeaponsActive |= weaponsactive & unknownmask; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_Specials() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->Specials = ivalue; + } +*/ +} + + +// global variables configuration commands pertaining to local ship ----------- +// +PRIVATE +void AcGlobals_SelectedLaser() +{ + /*int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + SelectedLaser = ivalue; + }*/ +} + +PRIVATE +void AcGlobals_SelectedMissile() +{ + /*int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + SelectedMissile = ivalue; + }*/ +} + +PRIVATE +void AcGlobals_CurGun() +{ + /*int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + CurGun = ivalue; + }*/ +} + +PRIVATE +void AcGlobals_CurLauncher() +{ + /*int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + CurLauncher = ivalue; + }*/ +} + +PRIVATE +void AcGlobals_AUX_HUD_PANEL_3_CONTROL() +{ + /*int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + AUX_HUD_PANEL_3_CONTROL = ivalue; + }*/ +} + +PRIVATE +void AcGlobals_AUX_HUD_PANEL_4_CONTROL() +{ + /*int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + AUX_HUD_PANEL_4_CONTROL = ivalue; + }*/ +} + +PRIVATE +void AcGlobals_TargetObjNumber() +{ + /*int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + TargetObjNumber = ivalue; + }*/ +} + + +// play specified sound effect ------------------------------------------------ +// +PRIVATE +void AcPlaySound() +{ + // dummy for compatibility +} + + +// flag whether audio stream has been started with an action command ---------- +// +PUBLIC int con_audio_stream_started = FALSE; + + +// start playing of specific audio stream ------------------------------------- +// +PRIVATE +void AcPlayStream() +{ +/* + char *streamname; + if ( AcFetchStringParam( &streamname, ACM_EAT_SPACE( ACM_PLAYSTREAM ) ) ) { + + if ( strlen( streamname ) + strlen( console_audio_stream_path ) > PATH_MAX ) { + // resulting file name too long + CON_AddLine( stream_name_inval ); + return; + } + + //NOTE: + // apart from its length the filename is + // not checked for validity in any way! + + // create full filename including path + char fname[ PATH_MAX + 1 ]; + strcpy( fname, console_audio_stream_path ); + strcat( fname, streamname ); + + // check first if file exists in pack or current directory + FILE *fp = SYS_fopen( streamname, "rb" ); + if ( fp == NULL ) { + + // check if file exists in audio stream path + fp = SYS_fopen( fname, "rb" ); + if ( fp == NULL ) { + CON_AddLine( stream_name_inval ); + return; + } + + //NOTE: + // we use SYS_fopen() here, because the streaming code + // also uses the SYS_f*() functions. + + } else { + + // strip path + strcpy( fname, streamname ); + } + SYS_fclose( fp ); + + // play audio stream (automatically determines stream's format) + int started = AUDs_PlayAudioStream( fname ); + + if ( started ) { + con_audio_stream_started = TRUE; + } else { + CON_AddLine( no_stream_started ); + } + } +*/ +} + + +// stop playing of currently active audio stream ------------------------------ +// +PRIVATE +void AcStopStream() +{ +/* + int stopped = AUDs_StopAudioStream(); + + if ( stopped ) { + con_audio_stream_started = FALSE; + } else { + CON_AddLine( no_stream_stopped ); + } +*/ +} + + +// set aux flag with ac. command ---------------------------------------------- +// +PRIVATE +void AcSetAuxFlag() +{ +/* + int32 params[ 2 ]; + if ( AcFetchIntParams( 2, params ) ) { + + if ( (dword)params[ 0 ] < MAX_AUX_ENABLING ) { + AuxEnabling[ params[ 0 ] ] = params[ 1 ]; + } + } +*/ +} + + +// set aux data with ac. command ---------------------------------------------- +// +PRIVATE +void AcSetAuxData() +{ +/* + int32 params[ 2 ]; + if ( AcFetchIntParams( 2, params ) ) { + + if ( (dword)params[ 0 ] < MAX_AUX_DATA ) { + AuxData[ params[ 0 ] ] = params[ 1 ]; + } + } +*/ +} + + +// set new refframe frequency ------------------------------------------------- +// +PRIVATE +void AcSetRefFrameFrequency() +{ +/* + int32 param; + if ( AcFetchIntParams( 1, ¶m ) ) { + + if ( RefFrameFrequency != param ) { + + RefFrameFrequency = param; + + // reinit frame timer to apply frequency change + SYSs_InitFrameTimer(); + } + } +*/ +} + + +// alter entry-mode flag ------------------------------------------------------ +// +PRIVATE +void AcSetEntryMode() +{ +/* + int32 param; + if ( AcFetchIntParams( 1, ¶m ) ) { + + EntryMode = param; + InFloatingMenu = EntryMode ? FloatingMenu : FALSE; + + // reset the floating menu state + if ( InFloatingMenu ) { + ActivateFloatingMenu( FALSE ); + } + } +*/ +} + + +// this gets called on execution instead of compilation, which is a nop ------- +// +PRIVATE +void AcIncludeDemo() +{ +/* + //NOTE: + // this command is a nop in a script file and should never + // occur in a compiled demo, since it will be substituted + // by the specified demo on compilation. + + CON_AddLine( only_for_compile ); +*/ +} + + +// this gets called on execution instead of compilation, which is a nop ------- +// +PRIVATE +void AcScheduleCommand() +{ +/* + //NOTE: + // this command is a nop in a script file. + // in a compiled demo this function will not be called at all. + + CON_AddLine( only_for_compile ); +*/ +} + + +// set the ambient light color ------------------------------------------------ +// +PRIVATE +void AcLightAmbient() +{ +/* + int32 params[ 4 ]; + if ( AcFetchIntParams( 4, params ) ) { + + LightColorAmbient.R = params[ 0 ]; + LightColorAmbient.G = params[ 1 ]; + LightColorAmbient.B = params[ 2 ]; + LightColorAmbient.A = params[ 3 ]; + } +*/ +} + + +// set the diffuse light color ------------------------------------------------ +// +PRIVATE +void AcLightDiffuse() +{ +/* + int32 params[ 4 ]; + if ( AcFetchIntParams( 4, params ) ) { + + LightColorDiffuse.R = params[ 0 ]; + LightColorDiffuse.G = params[ 1 ]; + LightColorDiffuse.B = params[ 2 ]; + LightColorDiffuse.A = params[ 3 ]; + } +*/ +} + + +// set the specular light color ----------------------------------------------- +// +PRIVATE +void AcLightSpecular() +{ +/* + int32 params[ 4 ]; + if ( AcFetchIntParams( 4, params ) ) { + + LightColorSpecular.R = params[ 0 ]; + LightColorSpecular.G = params[ 1 ]; + LightColorSpecular.B = params[ 2 ]; + LightColorSpecular.A = params[ 3 ]; + } +*/ +} + + +// cd audio: open drive ------------------------------------------------------- +// +PRIVATE +void AcCD_Open() +{ +/* + int32 param; + if ( AcFetchIntParams( 1, ¶m ) ) { + + AUDs_CDOpen( param ); + } +*/ +} + + +// cd audio: close drive ------------------------------------------------------ +// +PRIVATE +void AcCD_Close() +{ +// AUDs_CDClose(); +} + + +// cd audio: play audio track ------------------------------------------------- +// +PRIVATE +void AcCD_Play() +{ +/* + //NOTE: + // the from and to params (param 1 and 2) cannot be omitted + // when using this command. however, they can be set to -1 + // in order to avoid specifying specific from/to locations. + + int32 params[ 3 ]; + if ( AcFetchIntParams( 3, params ) ) { + + AUDs_CDPlay( params[ 0 ], params[ 1 ], params[ 2 ] ); + } +*/ +} + + +// cd audio: pause playing ---------------------------------------------------- +// +PRIVATE +void AcCD_Pause() +{ + //AUDs_CDPause(); +} + + +// cd audio: resume playing --------------------------------------------------- +// +PRIVATE +void AcCD_Resume() +{ + //AUDs_CDResume(); +} + + +// cd audio: stop playing ----------------------------------------------------- +// +PRIVATE +void AcCD_Stop() +{ + //AUDs_CDStop(); +} + + +// cd audio: set volume ------------------------------------------------------- +// +PRIVATE +void AcCD_Volume() +{ +/* + int32 param; + if ( AcFetchIntParams( 1, ¶m ) ) { + + AUDs_CDSetVolume( param ); + } +*/ +} + + +// list of valid action commands and functions to be called for each ---------- +// +act_command_s action_commands[] = { + + // general signature + { "ac.", NULL, ACF_NODIRECT | ACF_NOCOMPILE | ACF_NOPARAMS, 0 }, + + { "ac.wait", AcIdleCommand, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.pitch", AcAutoPitch, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.yaw", AcAutoYaw, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.roll", AcAutoRoll, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.slidex", AcAutoSlideX, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 1 }, + { "ac.slidey", AcAutoSlideY, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 1 }, + { "ac.move", AcAutoMove, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.camrot1", AcSetCamRotCol1, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + { "ac.camrot2", AcSetCamRotCol2, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + { "ac.camrot3", AcSetCamRotCol3, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + { "ac.camorigin", AcSetCamOrigin, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + + { "ac.fixrot1", AcSetFixedStarRotCol1, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + { "ac.fixrot2", AcSetFixedStarRotCol2, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + { "ac.fixrot3", AcSetFixedStarRotCol3, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + + { "ac.packet", AcPlayRemotePacket, ACF_NODIRECT | ACF_COMPILE | ACF_PACKETPARAM, 1 }, + + { "ac.fadeout", AcFadeOut, ACF_DIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.fadein", AcFadeIn, ACF_DIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.wfadeout", AcWhiteFadeOut, ACF_DIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.wfadein", AcWhiteFadeIn, ACF_DIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.black", AcBlackScreen, ACF_DIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.white", AcWhiteScreen, ACF_DIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.stdpalette", AcStandardPalette, ACF_DIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + + { "ac.savescreen", AcSaveDataInfo, ACF_DIRECT | ACF_NOCOMPILE | ACF_NOPARAMS, 0 }, + { "ac.savelist", AcSaveObjectList, ACF_DIRECT | ACF_NOCOMPILE | ACF_NOPARAMS, 0 }, + { "ac.savecam", AcSaveCamera, ACF_DIRECT | ACF_NOCOMPILE | ACF_NOPARAMS, 0 }, + { "ac.savefstars", AcSaveFixedStars, ACF_DIRECT | ACF_NOCOMPILE | ACF_NOPARAMS, 0 }, + { "ac.savepstars", AcSavePseudoStars, ACF_DIRECT | ACF_NOCOMPILE | ACF_NOPARAMS, 0 }, + { "ac.saveremote", AcSaveRemoteState, ACF_DIRECT | ACF_NOCOMPILE | ACF_NOPARAMS, 0 }, + + { "ac.killpstars", AcKillPseudoStars, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.addpstar", AcAddPseudoStar, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + + { "ac.preprestore", AcPrepareDataRestore, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.creatobj", AcCreateObject, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.creatextra", AcCreateExtra, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.destlist", AcDestroyObjectList, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.remoteplayer", AcRemotePlayer, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 4 }, + { "ac.remotematrix", AcRemoteMatrix, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 12 }, + { "ac.remotename", AcRemoteName, ACF_NODIRECT | ACF_COMPILE | ACF_STRINGPARAM, 1 }, + { "ac.remotejoin", AcRemoteJoin, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 3 }, + { "ac.remoteunjoin", AcRemoteUnjoin, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 3 }, + + { "ac.cleardemo", AcClearDemo, ACF_DIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.objmatrxcol1", AcObjectMatrxColumn1, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 4 }, + { "ac.objmatrxcol2", AcObjectMatrxColumn2, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 4 }, + { "ac.objmatrxcol3", AcObjectMatrxColumn3, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 4 }, + { "ac.objmatrxcol4", AcObjectMatrxColumn4, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 4 }, + + { "ac.laserspeed", AcSetLaserSpeed, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.laserdirvec", AcSetLaserDirVec, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + { "ac.laserowner", AcSetLaserOwner, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.misslspeed", AcSetMisslSpeed, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.missldirvec", AcSetMisslDirVec, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + + { "ac.misslowner", AcSetMisslOwner, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.missltarget", AcSetMisslTarget, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.mineowner", AcSetMineOwner, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.energyfield", AcEnergyField, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + { "ac.spreadfire", AcSpreadfire, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.lightningon", AcLightningOn, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.lightningoff", AcLightningOff, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + + { "ac.setobjid", AcSetObjectId, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.setobjhostid", AcSetObjectHostId, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.keypress", AcSimulateKeyPress, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.keyrelease", AcSimulateKeyRelease, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.ms.curdamage", AcMyShip_CurDamage, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.maxdamage", AcMyShip_MaxDamage, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.curenergy", AcMyShip_CurEnergy, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.maxenergy", AcMyShip_MaxEnergy, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.curspeed", AcMyShip_CurSpeed, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.maxspeed", AcMyShip_MaxSpeed, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.nummissls", AcMyShip_NumMissls, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.maxnummissls", AcMyShip_MaxNumMissls, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.numhommissls", AcMyShip_NumHomMissls, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.maxnumhommissls", AcMyShip_MaxNumHomMissls, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.nummines", AcMyShip_NumMines, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.maxnummines", AcMyShip_MaxNumMines, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.weapons", AcMyShip_Weapons, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.specials", AcMyShip_Specials, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.gl.selectedlaser", AcGlobals_SelectedLaser, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.gl.selectedmissile", AcGlobals_SelectedMissile, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.gl.curgun", AcGlobals_CurGun, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.gl.curlauncher", AcGlobals_CurLauncher, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.gl.panel3control", AcGlobals_AUX_HUD_PANEL_3_CONTROL, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.gl.panel4control", AcGlobals_AUX_HUD_PANEL_4_CONTROL, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.gl.targetobjnumber", AcGlobals_TargetObjNumber, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.writesmall", AcWriteSmall, ACF_DIRECT | ACF_COMPILE | ACF_STRINGPARAM, 1 }, + { "ac.writebig", AcWriteBig, ACF_DIRECT | ACF_COMPILE | ACF_STRINGPARAM, 1 }, + { "ac.writebig2", AcWriteBig2, ACF_DIRECT | ACF_COMPILE | ACF_STRINGPARAM, 1 }, + { "ac.writebig3", AcWriteBig3, ACF_DIRECT | ACF_COMPILE | ACF_STRINGPARAM, 1 }, + { "ac.cleartext", AcClearText, ACF_DIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + + { "ac.playstream", AcPlayStream, ACF_DIRECT | ACF_COMPILE | ACF_STRINGSTRIP, 1 }, + { "ac.stopstream", AcStopStream, ACF_DIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.playsound", AcPlaySound, ACF_DIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.aux", AcSetAuxFlag, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 2 }, + { "ac.entrymode", AcSetEntryMode, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.servermsg", AcPlayServerMessage, ACF_NODIRECT | ACF_COMPILE | ACF_STRINGSTRIP, 1 }, + + { "ac.helixon", AcHelixOn, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.helixoff", AcHelixOff, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + + { "ac.remotemaxplayers", AcRemoteMaxPlayers, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.include", AcIncludeDemo, ACF_NODIRECT | ACF_COMPILE | ACF_DEMOPARAM, 1 }, + + { "ac.ms.weaponsactive", AcMyShip_WeaponsActive, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.remoteweaponsactive", AcRemoteWeaponsActive, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.write", AcWriteConsoleText, ACF_NODIRECT | ACF_COMPILE | ACF_STRINGPARAM, 1 }, + { "ac.display", AcDisplayMessage, ACF_NODIRECT | ACF_COMPILE | ACF_STRINGSTRIP, 1 }, + + { "ac.cd.open", AcCD_Open, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.cd.close", AcCD_Close, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.cd.play", AcCD_Play, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 3 }, + { "ac.cd.pause", AcCD_Pause, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.cd.resume", AcCD_Resume, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.cd.stop", AcCD_Stop, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.cd.volume", AcCD_Volume, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.command", AcExecCommandString, ACF_NODIRECT | ACF_COMPILE | ACF_STRINGPARAM, 1 }, + + { "ac.classmapid", AcClassMapId, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.classmapname", AcClassMapName, ACF_NODIRECT | ACF_COMPILE | ACF_STRINGPARAM, 1 }, + + { "ac.auxdata", AcSetAuxData, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 2 }, + { "ac.refframes", AcSetRefFrameFrequency, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.schedule", AcScheduleCommand, ACF_NODIRECT | ACF_COMPILE | ACF_SCHEDPARAM, 1 }, + + { "ac.ambient", AcLightAmbient, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 4 }, + { "ac.diffuse", AcLightDiffuse, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 4 }, + { "ac.specular", AcLightSpecular, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 4 }, + + { "ac.ms.numpartmissls", AcMyShip_NumPartMissls, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.maxnumpartmissls", AcMyShip_MaxNumPartMissls, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.photonon", AcPhotonOn, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.photonoff", AcPhotonOff, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + + { "ac.empon", AcEmpOn, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.empoff", AcEmpOff, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.emp", AcEmp, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + + { NULL, NULL, ACF_NODIRECT | ACF_NOCOMPILE | ACF_NOPARAMS, 0 }, + +}; + + +// determine the number of parameter bytes of an action command --------------- +// +size_t GetActionParamSize( int actid, char *params ) +{ + ASSERT( actid > ACM_SIGNATURE ); + ASSERT( params != NULL ); + + size_t paramsize = 0; + + if ( action_commands[ actid ].flags & ACF_INTPARAMS ) { + paramsize = sizeof( int32 ) * action_commands[ actid ].numparameters; + } else if ( action_commands[ actid ].flags & ACF_FLOATPARAMS ) { + paramsize = sizeof( hprec_t ) * action_commands[ actid ].numparameters; + } else if ( action_commands[ actid ].flags & ACF_STRINGPARAM ) { + paramsize = strlen( params ) + 1; + } + + return paramsize; +} + + +// scheduled action commands -------------------------------------------------- +// +struct scheduled_command_s { + + refframe_t timestamp; + char* command; +}; + +#define MAX_SCHEDULED_COMMANDS 64 +static int num_scheduled_commands = 0; +static scheduled_command_s scheduled_commands[ MAX_SCHEDULED_COMMANDS ]; + + +// remainder of a wait interval split by a scheduled command ------------------ +// +static int scheduled_wait = 0; + + +// clear all scheduled action commands ---------------------------------------- +// +void ResetScheduledActions() +{ + num_scheduled_commands = 0; + scheduled_wait = 0; +} + + +// schedule an action command for automatic execution at a later time --------- +// +PRIVATE +size_t ScheduleCommand( int *params ) +{ + ASSERT( params != NULL ); +/* + // fetch delta time and command to schedule + int timedelta = SWAP_32( params[ 0 ] ); + int actid = SWAP_32( params[ 1 ] ); + + // calc absolute activation timestamp + refframe_t timestamp = demoinfo_curtime + timedelta; + + // insert at correct position if already commands scheduled + for ( int cid = 0; cid < num_scheduled_commands; cid++ ) { + + if ( scheduled_commands[ cid ].timestamp >= timestamp ) { + + // this also ensures the move works correctly + if ( num_scheduled_commands < MAX_SCHEDULED_COMMANDS ) { + num_scheduled_commands++; + } + + // move back commands scheduled for a later time + if ( cid < MAX_SCHEDULED_COMMANDS - 1 ) { + size_t movesize = ( num_scheduled_commands - cid - 1 ); + movesize *= sizeof( scheduled_command_s ); + memmove( &scheduled_commands[ cid + 1 ], &scheduled_commands[ cid ], movesize ); + } + + // store this command + scheduled_commands[ cid ].timestamp = timestamp; + scheduled_commands[ cid ].command = (char *) ¶ms[ 1 ]; + break; + } + } + + // insert if no commands scheduled or position should be last + if ( cid == num_scheduled_commands ) { + + // commands that exceed the available space will be dropped silently + if ( cid < MAX_SCHEDULED_COMMANDS ) { + scheduled_commands[ cid ].timestamp = timestamp; + scheduled_commands[ cid ].command = (char *) ¶ms[ 1 ]; + num_scheduled_commands++; + } + } + + // return number of parameter bytes to skip + size_t paramsize = sizeof( int ) * 2; + paramsize += GetActionParamSize( actid, (char *) ¶ms[ 2 ] ); + return paramsize; +*/ + ASSERT( FALSE ); + return 0; +} + + +// execute command in binary format as written by WriteActionCommand() -------- +// +int ExecBinCommands( char* &data, int interactive ) +{ +/* // non-interactive console mode + con_non_interactive = !interactive; + + // to remember the current replay position when + // it is temporarily set to a scheduled command + char *curpos = NULL; + +restartwait: + + // execute commands until wait encountered + for (;;) { + + // restore position after scheduled command + if ( curpos != NULL ) { + data = curpos; + curpos = NULL; + } + + // check for execution of scheduled command + if ( num_scheduled_commands > 0 ) { + + if ( scheduled_commands[ 0 ].timestamp == demoinfo_curtime ) { + + // temporarily jump to position of scheduled command + curpos = data; + data = scheduled_commands[ 0 ].command; + + // remove this command from scheduled commands + if ( num_scheduled_commands > 1 ) { + size_t movesize = ( num_scheduled_commands - 1 ); + movesize *= sizeof( scheduled_command_s ); + memmove( &scheduled_commands[ 0 ], &scheduled_commands[ 1 ], movesize ); + } + num_scheduled_commands--; + } + } + + // for regular (non-scheduled) commands + if ( curpos == NULL ) { + + // exit loop on implied wait command + if ( scheduled_wait > 0 ) { + break; + } + + // count executed commands + demoinfo_curline++; + } + + // fetch command id + int actid = SWAP_32( *(int *)data ); + ASSERT( ( actid >= ACM_SIGNATURE ) && ( actid < ACM_NUM_COMMANDS ) ); + + // stop execution if end of command file reached + if ( actid == ACM_SIGNATURE ) { + bin_params = NULL; + con_non_interactive = FALSE; + return FALSE; + } + + data += sizeof( actid ); + bin_params = data; + + // exit loop on wait command + if ( actid == ACM_IDLEWAIT ) { + break; + } + + // check for packet replay + if ( action_commands[ actid ].flags & ACF_PACKETPARAM ) { + + // replay packet and get pointer advance + size_t advance = REC_PlayRemotePacketBin( (NetPacketExternal *) bin_params ); + + // check for invalid pointer advance ( -1 ... invalid packet ) + if ( advance == (size_t)-1 ) { + bin_params = NULL; + con_non_interactive = FALSE; + return FALSE; + } + + data += advance; + continue; + } + + // check for command scheduling + if ( action_commands[ actid ].flags & ACF_SCHEDPARAM ) { + // schedule command and advance pointer + data += ScheduleCommand( (int *) bin_params ); + continue; + } + + // determine how many parameter bytes need to be skipped. + // we do this before calling the action function because + // it might destroy its string parameter while parsing. + size_t paramsize = GetActionParamSize( actid, bin_params ); + + // call corresponding action function + // (it knows the type of its parameters) + ASSERT( action_commands[ actid ].func != NULL ); + (*action_commands[ actid ].func)(); + + // skip command's parameters (already read by action function) + data += paramsize; + } + + // wait command must not be scheduled + ASSERT( curpos == NULL ); + + // determine length of next wait interval + int waitcount; + if ( scheduled_wait > 0 ) { + + // completion of wait interval split by scheduled command + waitcount = scheduled_wait; + scheduled_wait = 0; + + } else { + + // preadvance over wait argument + data += sizeof( int32 ); + + // process wait + int32 suppliedwait; + if ( !AcFetchIntParams( 1, &suppliedwait ) ) { + + ASSERT( 0 ); + CON_AddLine( invalid_bin_wait ); + goto restartwait; + } + + waitcount = suppliedwait; + } + + // consume zero-waits transparently + if ( waitcount == 0 ) { + goto restartwait; + } + + ASSERT( waitcount > 0 ); + if ( waitcount < 0 ) { + CON_AddLine( invalid_bin_wait ); + goto restartwait; + } + + // check for scheduled commands in the middle of the next wait interval + if ( num_scheduled_commands > 0 ) { + ASSERT( demoinfo_curtime < scheduled_commands[ 0 ].timestamp ); + if ( demoinfo_curtime + waitcount > scheduled_commands[ 0 ].timestamp ) { + scheduled_wait = waitcount; + waitcount = scheduled_commands[ 0 ].timestamp - demoinfo_curtime; + scheduled_wait -= waitcount; + } + } + + // set duration to wait for + //CurActionWait = waitcount; + + // remember for info + demoinfo_lastwait = (refframe_t) waitcount; + + // flag must be reset + con_non_interactive = FALSE; + + bin_params = NULL; +*/ + return TRUE; +} + + +// save game state to current recording --------------------------------------- +// +void SaveGameState() +{ + //NOTE: + // this function is called by CON_EXT::StartRecording() to save + // the game state before a recording is started. + + AcSaveDataInfo(); +} + + +// include an entire demo file in the current compilation --------------------- +// +PRIVATE +int IncludeDemoFile( FILE *fp ) +{ +/* ASSERT( fp != NULL ); + + // read demo name + char *demoname; + if ( AcFetchStringParam( &demoname, TRUE ) ) { + + // open demo for inclusion + FILE *cpfp = DEMO_BinaryOpenDemo( demoname ); + if ( cpfp == NULL ) { + strcpy( paste_str, "demo file not found. (" ); + strcat( paste_str, demoname ); + strcat( paste_str, CON_FILE_COMPILED_EXTENSION ); + strcat( paste_str, ")" ); + CON_AddLine( paste_str ); + return TRUE; + } + + // skip header if present + DEMO_ParseDemoHeader( cpfp, -1, FALSE ); + + // demo will be copied in chunks + #define INCLUDE_BLOCK_SIZE 16384 + char *cpblock = (char *) ALLOCMEM( INCLUDE_BLOCK_SIZE ); + if ( cpblock == NULL ) + OUTOFMEM( 0 ); + + // paste in entire demo in chunks + size_t numread = 1; + while ( numread > 0 ) { + numread = fread( cpblock, 1, INCLUDE_BLOCK_SIZE, cpfp ); + if ( fwrite( cpblock, 1, numread, fp ) != numread ) { + CON_AddLine( compile_write_err ); + FREEMEM( cpblock ); + return FALSE; + } + } + + FREEMEM( cpblock ); + fclose( cpfp ); + + // strip off terminating eof marker + fseek( fp, -sizeof( int ), SEEK_CUR ); + } +*/ + return TRUE; +} + + +// write int parameters of action command in binary format to file ------------ +// +PRIVATE +int WriteActionIntParams( FILE *fp, int paranum ) +{ + ASSERT( fp != NULL ); + ASSERT( paranum > 0 ); + + // write int parameters + int32 *intparams = (int32 *) ALLOCMEM( sizeof( int32 ) * paranum * 2 ); + int32 *intparams_swapped = &intparams[ paranum ]; + if ( AcFetchIntParams( paranum, intparams ) ) { + + // must be written in little-endian format + SwapParams_int( paranum, intparams, intparams_swapped ); + + if ( fwrite( intparams_swapped, sizeof( int32 ), paranum, fp ) != (unsigned int)paranum ) { + CON_AddLine( compile_write_err ); + FREEMEM( intparams ); + return FALSE; + } + + } else { + + CON_AddLine( compile_arg_inval ); + } + + FREEMEM( intparams ); + + return TRUE; +} + + +// write float parameters of action command in binary format to file ---------- +// +PRIVATE +int WriteActionFloatParams( FILE *fp, int paranum ) +{ + ASSERT( fp != NULL ); + ASSERT( paranum > 0 ); + + // write float parameters + hprec_t *floatparams = (hprec_t *) ALLOCMEM( sizeof( hprec_t ) * paranum * 2 ); + hprec_t *floatparams_swapped = &floatparams[ paranum ]; + if ( AcFetchFloatParams( paranum, floatparams ) ) { + + // must be written in little-endian format + SwapParams_hprec( paranum, floatparams, floatparams_swapped ); + + if ( fwrite( floatparams_swapped, sizeof( hprec_t ), paranum, fp ) != (unsigned int)paranum ) { + CON_AddLine( compile_write_err ); + FREEMEM( floatparams ); + return FALSE; + } + + } else { + + CON_AddLine( compile_arg_inval ); + } + + FREEMEM( floatparams ); + + return TRUE; +} + + +// write string parameter of action command in binary format to file ---------- +// +PRIVATE +int WriteActionStringParam( FILE *fp, dword flags ) +{ + ASSERT( fp != NULL ); + + // read string parameter + char *strparam; + if ( AcFetchStringParam( &strparam, ACF_EAT_SPACE( flags ) ) ) { + + unsigned int slen = strlen( strparam ) + 1; + if ( fwrite( strparam, 1, slen, fp ) != slen ) { + CON_AddLine( compile_write_err ); + return FALSE; + } + + } else { + + CON_AddLine( compile_arg_inval ); + } + + return TRUE; +} + + +// write packet parameter of action command in binary format to file ---------- +// +PRIVATE +int WriteActionPacketParam( FILE *fp ) +{ + ASSERT( fp != NULL ); + + int rc = TRUE; +/* + // read session and packet ids and fetch corresponding packet + int32 params[ 2 ]; + if ( AcFetchIntParams( 2, params ) ) { + + // fetch packet + NetPacketExternal* ext_gamepacket = (NetPacketExternal*) ALLOCMEM( RECORD_PACKET_SIZE ); + size_t psize = REC_FetchRemotePacket( ext_gamepacket, params[ 0 ], params[ 1 ] ); + + // write packet if valid + if ( psize > 0 ) { + if ( fwrite( ext_gamepacket, 1, psize, fp ) != psize ) { + CON_AddLine( compile_write_err ); + rc = FALSE; + } + } else { + CON_AddLine( compile_pkt_inval ); + rc = FALSE; + } + + FREEMEM( ext_gamepacket ); + + } else { + + CON_AddLine( compile_arg_inval ); + } +*/ + ASSERT( FALSE ); + + return rc; +} + + +// forward declaration -------------------------------------------------------- +// +PRIVATE +void ExecActionCommand( char *cstr ); + + +// write a scheduled command into the current compilation --------------------- +// +PRIVATE +int WriteScheduledCommand( FILE *fp ) +{ + ASSERT( fp != NULL ); + + // prevent recursive call (scheduling of schedule command) + static int scheduled_command_writing_active = FALSE; + if ( scheduled_command_writing_active ) { + CON_AddLine( invalid_arg ); + return FALSE; + } + scheduled_command_writing_active = TRUE; + + // parse delta time parameter + char *timeparam = strtok( NULL, " " ); + if ( timeparam == NULL ) { + CON_AddLine( arg_missing ); + return FALSE; + } + + char *errpart; + int timedelta = strtol( timeparam, &errpart, int_calc_base ); + if ( *errpart != 0 ) { + CON_AddLine( invalid_arg ); + return FALSE; + } + + // write delta time in little-endian format + timedelta = SWAP_32( timedelta ); + if ( fwrite( &timedelta, sizeof( timedelta ), 1, fp ) != 1 ) { + CON_AddLine( compile_write_err ); + return FALSE; + } + + // append scheduled command as parameter after scheduling prefix + ExecActionCommand( NULL ); + + scheduled_command_writing_active = FALSE; + return TRUE; +} + + +// write action command in binary format to file ------------------------------ +// +PRIVATE +int WriteActionCommand( FILE *fp, int actid ) +{ + ASSERT( fp != NULL ); + ASSERT( actid > ACM_SIGNATURE ); + + dword flags = action_commands[ actid ].flags; + int paranum = action_commands[ actid ].numparameters; + + // exit if command may not be compiled + if ( ( flags & ACF_COMPILE ) == 0 ) { + CON_AddLine( compile_non_comp ); + return TRUE; + } + + // check for demo inclusion + // (command will be substituted) + if ( flags & ACF_DEMOPARAM ) { + return IncludeDemoFile( fp ); + } + + // must be written in little-endian format + actid = SWAP_32( actid ); + + // write id of command + if ( fwrite( &actid, sizeof( actid ), 1, fp ) != 1 ) { + CON_AddLine( compile_write_err ); + return FALSE; + } + + if ( flags & ACF_INTPARAMS ) { + + // write int parameters to file + if ( !WriteActionIntParams( fp, paranum ) ) { + return FALSE; + } + + } else if ( flags & ACF_FLOATPARAMS ) { + + // write float parameters to file + if ( !WriteActionFloatParams( fp, paranum ) ) { + return FALSE; + } + + } else if ( flags & ACF_STRINGPARAM ) { + + // write string parameter to file + ASSERT( paranum == 1 ); + if ( !WriteActionStringParam( fp, flags ) ) { + return FALSE; + } + + } else if ( flags & ACF_PACKETPARAM ) { + + // write packet parameter to file + if ( !WriteActionPacketParam( fp ) ) { + return FALSE; + } + + } else if ( flags & ACF_SCHEDPARAM ) { + + // write scheduled command to file + if ( !WriteScheduledCommand( fp ) ) { + return FALSE; + } + } + + return TRUE; +} + + +// call action function corresponding to action command or compile it --------- +// +INLINE +void CallActionFunction( int actid ) +{ + ASSERT( actid > ACM_SIGNATURE ); + + if ( compile_script ) { + + // if fp is NULL write error occurred earlier on + if ( compile_fp != NULL ) { + + // write command to file but do not execute it + if ( !WriteActionCommand( compile_fp, actid ) ) { + // write error cleanup + fclose( compile_fp ); + compile_fp = NULL; + } + } + + } else { + + // call corresponding action function + ASSERT( action_commands[ actid ].func != NULL ); + (*action_commands[ actid ].func)(); + } +} + + +// lookup action command and execute it --------------------------------------- +// +PRIVATE +void ExecActionCommand( char *cstr ) +{ + // scan table + char *aspec = strtok( cstr, " " ); + int aid; + for ( aid = ACM_SIGNATURE + 1; ACMSTR( aid ) != NULL; aid++ ) { + + if ( strcmp( ACMSTR( aid ), aspec ) == 0 ) { + + dword flags = action_commands[ aid ].flags; + if ( ( action_commands[ aid ].func != NULL ) && + ( processing_batch || ( flags & ACF_DIRECT ) ) ) { + + CallActionFunction( aid ); + + } else { + + CON_AddLine( non_batch_use ); + } + break; + } + } + + if ( ACMSTR( aid ) == NULL ) { + + // no action command with specified name found + CON_AddLine( invalid_action ); + } +} + + +// exec action command (command prefixed with "ac.") -------------------------- +// +void ActionCommand( char *cstr ) +{ + ASSERT( cstr != NULL ); + + // exit if action commands currently not allowed + if ( preempt_action_commands ) { + CON_AddLine( action_preempted ); + return; + } + + char *bdot = cstr + ACMLEN( ACM_SIGNATURE ); + if ( *bdot != 0 ) { + + // look up command and execute it + ExecActionCommand( cstr ); + + } else { + + // no action specified after "ac." + CON_AddLine( no_action_found ); + } +} + + +// module registration function ----------------------------------------------- +// +REGISTER_MODULE( CON_ACT_SV ) +{ + // reset mapping table for class ids + int oldflag = SV_CLASS_MAP_TABLE_DISABLE_RESET; + SV_CLASS_MAP_TABLE_DISABLE_RESET = FALSE; + ResetClassMapTable(); + SV_CLASS_MAP_TABLE_DISABLE_RESET = oldflag; +} + + + diff --git a/src/parsec_server/con_aux_sv.cpp b/src/parsec_server/con_aux_sv.cpp new file mode 100755 index 0000000..8b73dc6 --- /dev/null +++ b/src/parsec_server/con_aux_sv.cpp @@ -0,0 +1,236 @@ +/* + * PARSEC - SERVER Verbose Server Commands + * + * $Author: uberlinuxguy $ - $Date: 2004/09/26 03:43:47 $ + * + * Orginally written by: + * Copyright (c) Clemens Beer 2001 + * Copyright (c) Markus Hadwiger 1998-2000 + * + * 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 2 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +// C library +#include +#include +#include +#include + +// compilation flags/debug support +#include "config.h" +#include "debug.h" + +// general definitions +#include "general.h" +#include "objstruc.h" + +// global externals +#include "globals.h" + +// rendering subsystem +//#include "r_patch.h" +//#include "r_supp.h" + +// subsystem headers +#include "net_defs.h" + +// local module header +#include "con_aux_sv.h" + +// proprietary module headers +#include "con_com_sv.h" +#include "con_int_sv.h" +#include "g_main_sv.h" +//#include "e_supp.h" +//#include "net_csdf.h" +#include "net_ports.h" +#include "e_gameserver.h" + +// flags +#define REGISTER_VERBOSE_SV_COMMANDS +//#define EXCLUDE_SPECIAL_SV_FLAGS + + +//NOTE: +// this module is only loosely related to the CONS_AUX.H +// header. that is, it may be omitted from linking +// entirely, if there should be no verbose SV commands. +// apart from this, project functionality will not be +// reduced. CONS_AUX.H must always be part of the project. + + +/* +//FIXME: +// perform remote event syncing for certain SV flags ------------------------- +// +#define DEF_RMEV_STATESYNC( f, k, v ) \ +PUBLIC \ +void RESync##f() \ +{ \ + if ( !NET_RmEvAllowed( RE_STATESYNC ) ) \ + return; \ + NET_RmEvStateSync( (k), (v) ); \ +} + +//FIXME_GAMESERVER: these fields are all part of the server config object + +DEF_RMEV_STATESYNC( NebulaId, RMEVSTATE_NEBULAID, AUXDATA_BACKGROUND_NEBULA_ID ); +DEF_RMEV_STATESYNC( Amazing, RMEVSTATE_AMAZING, AUXDATA_SKILL_AMAZING_TIME ); +DEF_RMEV_STATESYNC( Brilliant, RMEVSTATE_BRILLIANT, AUXDATA_SKILL_BRILLIANT_TIME ); +DEF_RMEV_STATESYNC( KillLimit, RMEVSTATE_KILLLIMIT, AUX_KILL_LIMIT_FOR_GAME_END ); + +*/ + +void G_RealizeGameVars() +{ + TheGame->RealizeVariables(); +} + +// for registration of SV flags/data as integer variable commands ----------------- +// +PRIVATE +int_command_s verbose_sv_commands[] = { + + { 0x80, "sv.package_scripts", 0, 1, &SV_PACKAGE_SCRIPTS, NULL, NULL, TRUE }, + { 0x80, "sv.console.level_messages", 0, 1, &SV_CONSOLE_LEVEL_MESSAGES, NULL, NULL, TRUE }, + { 0x80, "sv.package_scripts.list", 0, 1, &SV_PACKAGE_SCRIPT_LISTING, NULL, NULL, TRUE }, + { 0x80, "sv.class_map_table.disable_reset", 0, 1, &SV_CLASS_MAP_TABLE_DISABLE_RESET, NULL, NULL, FALSE }, + { 0x80, "aux.netcode.flags", 0, 16, &AUX_NETCODE_FLAGS, NULL, NULL, 0 }, +#ifdef ENABLE_CHEAT_COMMANDS + { 0x80, "sv.cheats.energy_checks", 0, 1, &SV_CHEAT_ENERGY_CHECKS, NULL, NULL, 0 }, + { 0x80, "sv.cheats.device_checks", 0, 1, &SV_CHEAT_DEVICE_CHECKS, NULL, NULL, 0 }, +#endif // ENABLE_CHEAT_COMMANDS + { 0x80, "aux_enable_object_overloading", 0, 1, &SV_OBJECTCLASSES_OVERLOADING, NULL, NULL, FALSE }, + { 0x80, "sv.objectclasses.overloading", 0, 1, &SV_OBJECTCLASSES_OVERLOADING, NULL, NULL, FALSE }, + + { 0x80, "sv.game.extras.autocreate", 0, 1, &SV_GAME_EXTRAS_AUTOCREATE, NULL, NULL, TRUE }, + { 0x80, "sv.game.extras.max", 0, 100, &SV_GAME_EXTRAS_MAXNUM, NULL, NULL, 20 }, + { 0x80, "sv.game.extras.testplace", 0, 1, &SV_GAME_EXTRAS_TESTPLACE, NULL, NULL, 0 }, + { 0x80, "sv.game.killlimit", 1, 4096, &SV_GAME_KILLLIMIT, G_RealizeGameVars, NULL, DEFAULT_KILL_LIMIT }, + { 0x80, "sv.game.timelimit", 1, 86400, &SV_GAME_TIMELIMIT, G_RealizeGameVars, NULL, DEFAULT_GAME_TIMELIMIT_SEC }, + { 0x80, "sv.game.restart.timeout", 0, 600, &SV_GAME_RESTART_TIMEOUT, G_RealizeGameVars, NULL, DEFAULT_RESTART_TIMELIMIT_SEC }, + + { 0x80, "sv.masterserver.sendheartbeat", 0, 1, &SV_MASTERSERVER_SENDHEARTBEAT, NULL, NULL, TRUE }, + { 0x80, "sv.serverid", 0, 0xFFFF, &SV_SERVERID, NULL, NULL, 0 }, + { 0x80, "sv.fedid", 0, 0xFFFF, &SV_FEDID, NULL, NULL, 0 }, + { 0x80, "sv.netconf.port", 1024, 0xFFFF,&SV_NETCONF_PORT, NULL, NULL, DEFAULT_GAMESERVER_UDP_PORT }, + + { 0x80, "sv.debug.netstream.dump", 0, 15, &SV_DEBUG_NETSTREAM_DUMP, NULL, NULL, 0 }, + { 0x80, "sv.debug.console.messages", 0, 1, &SV_DEBUG_CONSOLE_MESSAGES, NULL, NULL, 0 }, + + { 0x80, "sv.game.workdir.force_current", 0, 1, &SV_GAME_WORKDIR_FORCE_CURRENT, NULL, NULL, 0 }, + { 0x80, "sv.game.filepath.force_curent", 0, 1, &SV_GAME_FILEPATH_FORCE_CURRENT, NULL, NULL, 0 }, + + { 0x80, "sv.game.extras.maxnum", 0, 1000, &SV_GAME_EXTRAS_MAXNUM, NULL, NULL, 0 }, + { 0x80, "aux_disable_package_data_files", 0, 1, &AUX_DISABLE_PACKAGE_DATA_FILES , NULL, NULL, 0 }, + { 0x80, "aux_disable_package_scripts", 0, 1, &AUX_DISABLE_PACKAGE_SCRIPTS, NULL, NULL, 0 }, + +}; + +#define NUM_VERBOSE_SV_COMMANDS CALC_NUM_ARRAY_ENTRIES( verbose_sv_commands ) + + +// dummy command handler for all commands that are invalid for the server +// +int Cmd_DUMMY( char *classstr ) +{ + return TRUE; +} + + +// register all commands that are NOP for the server, to allow sharing console scripts +// between server and client +PRIVATE +void RegisterServerNOPCommands() +{ + + const char* szNOPCommands[] = { "shipdesc", + "classiter", + "classpart", + "shader.set", + NULL }; + + user_command_s regcom; + memset( ®com, 0, sizeof( user_command_s ) ); + + for( int nNOPCommand = 0; szNOPCommands[ nNOPCommand ] != NULL; nNOPCommand++ ) { + // register dummy command + regcom.command = szNOPCommands[ nNOPCommand ]; + regcom.numparams = 1; + regcom.execute = Cmd_DUMMY; + regcom.statedump = NULL; + CON_RegisterUserCommand( ®com ); + } +} + + +// module registration function ----------------------------------------------- +// +void CON_AUX_SV_Register() +{ + ASSERT( NUM_VERBOSE_SV_COMMANDS <= AUX_ARRAY_NUM_ENTRIES_USED ); + +#ifdef REGISTER_VERBOSE_SV_COMMANDS + unsigned int csv; + // register SV flags + for ( csv = 0; csv < NUM_VERBOSE_SV_COMMANDS; csv++ ) { + + //NOTE: + // bit 7 of the persistence field is used to denote + // special SV flags that may be excluded from registration. + + #ifdef EXCLUDE_SPECIAL_SV_FLAGS + + if ( verbose_sv_commands[ csv ].persistence & 0x80 ) + continue; + + #endif + + // destructive but doesn't matter here + verbose_sv_commands[ csv ].persistence &= ~0x80; + + CON_RegisterIntCommand( verbose_sv_commands + csv ); + } + +#endif // REGISTER_VERBOSE_SV_COMMANDS + + // init sv flags with default value + for( csv = 0; csv < NUM_VERBOSE_SV_COMMANDS; csv++ ) { + + int_command_s* cmd = &verbose_sv_commands[ csv ]; + + if ( ( cmd->bmin <= cmd->default_val ) && ( cmd->bmax >= cmd->default_val ) ) { + *cmd->intref = cmd->default_val; + + // do not call realize functions if the server is a master + if ( cmd->realize != NULL && !TheServer->GetServerIsMaster()) + cmd->realize(); + + } else { + // default value specified was not inside min/max bounds + ASSERT( FALSE ); + + // default to min + *cmd->intref = cmd->bmin; + + // do not call realize functions if the server is a master + if ( cmd->realize != NULL && !TheServer->GetServerIsMaster()) + cmd->realize(); + } + } + + // register all commands that are NOPs for the server + RegisterServerNOPCommands(); +} diff --git a/src/parsec_server/con_com_sv.cpp b/src/parsec_server/con_com_sv.cpp new file mode 100755 index 0000000..72c4c96 --- /dev/null +++ b/src/parsec_server/con_com_sv.cpp @@ -0,0 +1,849 @@ +/* + * PARSEC - Common Commands + * + * $Author: uberlinuxguy $ - $Date: 2004/09/26 03:43:47 $ + * + * Orginally written by: + * Copyright (c) Clemens Beer 2002 + * Copyright (c) Markus Hadwiger 1996-1999 + * + * 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 2 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +// C library +#include +#include +#include +#include +#include + +// compilation flags/debug support +#include "config.h" +#include "debug.h" + +// general definitions +#include "general.h" +#include "objstruc.h" +#include "od_props.h" + +// global externals +#include "globals.h" +#include "e_world_trans.h" + +// subsystem headers +//#include "aud_defs.h" +//#include "inp_defs.h" +#include "net_defs.h" +//#include "vid_defs.h" + +// local module header +#include "con_com_sv.h" + +// proprietary module headers +//#include "con_act.h" +#include "con_arg.h" +#include "con_aux_sv.h" +//#include "con_cani.h" +//#include "con_conf.h" +#include "con_ext_sv.h" +#include "con_info_sv.h" +#include "con_int_sv.h" +#include "con_list_sv.h" +#include "con_load_sv.h" +#include "con_main_sv.h" +//#include "con_say.h" +//#include "con_shad.h" +#include "con_std_sv.h" +//#include "e_demo.h" +//#include "e_supp.h" +//#include "g_supp.h" +//#include "h_supp.h" +#include "inp_main_sv.h" +//#include "m_main.h" +//#include "net_conn.h" +//#include "obj_ctrl.h" +#include "e_gameserver.h" +#include "sys_date.h" +#include "sys_path.h" +//#include "vid_init.h" +//#include "vid_plug.h" + + + +// generic string paste area -------------------------------------------------- +// +#define PASTE_STR_LEN 255 +static char paste_str[ PASTE_STR_LEN + 1 ]; + + +// string constants ----------------------------------------------------------- +// +static char base_str[] = "base is set to dec."; +#define BASE_INSERT_POS 15 +static char base_dec[] = "dec."; +static char base_hex[] = "hex."; +static char base_oct[] = "oct."; +static char base_set_to_dec[] = "base set to dec."; +static char base_set_to_hex[] = "base set to hex."; +static char base_set_to_oct[] = "base set to oct."; +static char info_sep_line[] = "-----------------------------------------------"; +PUBLIC char dont_use_params[] = "this command takes no parameters."; +static char server_name_missing[] = "server must be supplied."; +static char mode_number_invalid[] = "invalid mode number."; +static char mode_spec_invalid[] = "invalid mode specifier. use something like \"640x480x32\"."; +static char mode_spec_unavail[] = "this mode is not available in the current video subsystem."; +static char mode_modifier_invalid[] = "invalid mode modifier. use \"fullscreen\" or \"windowed\"."; +static char only_alpha_chars[] = "name must not contain non-alphabetic characters."; +static char name_change_preempted[] = "name change preempted. please try again."; + + +// remove all objects (command "objectclear") --------------------------------- +// +PRIVATE +void Cmd_OBJECTCLEAR() +{ + // free objects and particles + KillAllObjects(); +} + + +// print object counts for all object lists (command "objectcount") ----------- +// +PRIVATE +void Cmd_OBJECTCOUNT() +{ + sprintf( paste_str, "ships :%3d", TheWorld->GetNumShipObjects() ); + CON_AddLine( paste_str ); + sprintf( paste_str, "lasers :%3d", TheWorld->GetNumLaserObjects() ); + CON_AddLine( paste_str ); + sprintf( paste_str, "missiles:%3d", TheWorld->GetNumMisslObjects() ); + CON_AddLine( paste_str ); + sprintf( paste_str, "extras :%3d (obj, counted %d) and %d particle", TheWorld->GetNumExtraObjects(), TheWorld->m_nCurrentNumExtras, TheWorld->m_nCurrentNumPrtExtras ); + CON_AddLine( paste_str ); + sprintf( paste_str, "customs :%3d", TheWorld->GetNumCustmObjects() ); + CON_AddLine( paste_str ); +} + + +// display heap info (command "heap") ----------------------------------------- +// +#ifdef PARSEC_DEBUG +PRIVATE +int Cmd_HEAP( char *params ) +{ + ASSERT( params != NULL ); + USERCOMMAND_NOPARAM( params ); + + extern unsigned int Dyn_Mem_Size; + extern unsigned int Num_Allocs; + extern unsigned int Num_Frees; + + sprintf( paste_str, "heapsize: %.2fmb :%d", (float) Dyn_Mem_Size / ( 1024 * 1024 ), Dyn_Mem_Size ); + CON_AddLine( paste_str ); + sprintf( paste_str, "memobjs : %d", Num_Allocs - Num_Frees ); + CON_AddLine( paste_str ); + + return TRUE; +} +#endif // PARSEC_DEBUG + + +// show position of local ship (command "showposition") ----------------------- +// +PRIVATE +void Cmd_SHOWPOSITION() +{ + //FIXME: we need a shipindex parameter here + + /*sprintf( paste_str, "x position: %13f", GEOMV_TO_FLOAT( MyShip->ObjPosition[ 0 ][ 3 ] ) ); + CON_AddLine( paste_str ); + + sprintf( paste_str, "y position: %13f", GEOMV_TO_FLOAT( MyShip->ObjPosition[ 1 ][ 3 ] ) ); + CON_AddLine( paste_str ); + + sprintf( paste_str, "z position: %13f", GEOMV_TO_FLOAT( MyShip->ObjPosition[ 2 ][ 3 ] ) ); + CON_AddLine( paste_str );*/ +} + +// open output script for writing (don't overwrite existing file) ------------- +// +PRIVATE +int Cmd_Create( char *command ) +{ + return OpenOutputBatch( command, CM_CREATE ); +} + + +// open output script for writing (overwrite existing file) ------------------- +// +PRIVATE +int Cmd_Open( char *command ) +{ + return OpenOutputBatch( command, CM_OPEN ); +} + + +// append to output script ---------------------------------------------------- +// +PRIVATE +int Cmd_Append( char *command ) +{ + return OpenOutputBatch( command, CM_APPEND ); +} + + +// record demo script after saving state -------------------------------------- +// +PRIVATE +int Cmd_Recdem( char *command ) +{ + return StartRecording( command, TRUE ); +} + + +// record demo script without saving state first ------------------------------ +// +PRIVATE +int Cmd_Record( char *command ) +{ + return StartRecording( command, FALSE ); +} + + +// print parsec build info (command "build") ---------------------------------- +// +PRIVATE +int Cmd_BuildInfo( char *cstr ) +{ + ASSERT( cstr != NULL ); + HANDLE_COMMAND_DOMAIN_SEP( cstr ); + + // split off first token (detail) + char *dstr = strtok( cstr, " " ); + if ( dstr == NULL ) { + // display basic build info + CON_AddLine( build_text ); + CON_AddLine( build_date ); + CON_AddLine( build_time ); + return TRUE; + } + + // check if more than one parameter + if ( strtok( NULL, " " ) != NULL ) { + CON_AddLine( too_many_args ); + return TRUE; + } + + // check for detail spec + if ( strcmp( dstr, "x" ) == 0 ) { + + CON_AddLine( info_sep_line ); + CON_AddLine( build_text ); + CON_AddLine( info_sep_line ); + CON_AddLine( build_date ); + CON_AddLine( build_time ); + CON_AddLine( info_sep_line ); + //DisplayCurrentNetSubsys(); + CON_AddLine( info_sep_line ); + CON_AddLine( build_comp ); + CON_AddLine( build_bind ); + CON_AddLine( build_endn ); + CON_AddLine( info_sep_line ); + + } else { + + CON_AddLine( invalid_arg ); + } + + return TRUE; +} + + +// exec display command (display arbitrary text in message area) -------------- +// +PRIVATE +int Cmd_DisplayText( char *cstr ) +{ + ASSERT( cstr != NULL ); + HANDLE_COMMAND_DOMAIN( cstr ); + + const char *scan = GetStringBehindCommand( cstr, FALSE ); + + if ( ( scan != NULL ) && ( strlen( scan ) <= MAX_MESSAGELEN ) ) { + //FIXME: evt. precede text with "MESSAGE: " + MSGOUT( scan ); + } + + // recognize always (implicitly reserves domain) + return TRUE; +} + + +// exec write command (display arbitrary text in console) --------------------- +// +PRIVATE +int Cmd_WriteText( char *cstr ) +{ + //NOTE: + // this command normally only makes sense if + // used from within a console script. + + ASSERT( cstr != NULL ); + HANDLE_COMMAND_DOMAIN( cstr ); + + const char *scan = GetStringBehindCommand( cstr, TRUE ); + + // output string in console (new-line possible) + if ( scan != NULL ) { + MSGPUT( "\n::%s", scan ); + } + + // recognize always (implicitly reserves domain) + return TRUE; +} + + +// set current working directory (general use) -------------------------------- +// +PRIVATE +int Cmd_SetPathWorkingDirectory( char *command ) +{ + ASSERT( command != NULL ); + HANDLE_COMMAND_DOMAIN( command ); + + if ( SetSingleStringCommand( command, CurWorkDir, PATH_MAX ) ) { + + // process file name + char *path = SYSs_ProcessPathString( CurWorkDir ); + if ( path != CurWorkDir ) { + strncpy( CurWorkDir, path, PATH_MAX ); + CurWorkDir[ PATH_MAX ] = 0; + } + } + + // recognize always (implicitly reserves domain) + return TRUE; +} + + +// set file path for intro animation ------------------------------------------ +// +PRIVATE +int Cmd_SetPathAnimIntro( char *command ) +{ + ASSERT( command != NULL ); + HANDLE_COMMAND_DOMAIN( command ); +/* + extern char demo_movie_name[]; + if ( SetSingleStringCommand( command, demo_movie_name, PATH_MAX ) ) { + + // process file name and use current workdir + strcpy( demo_movie_name, SubstCurWorkDir( demo_movie_name ) ); + } +*/ + // recognize always (implicitly reserves domain) + return TRUE; +} + + +// set file path for all audio streams ---------------------------------------- +// +PRIVATE +int Cmd_SetPathAudioStreams( char *command ) +{ + ASSERT( command != NULL ); + HANDLE_COMMAND_DOMAIN( command ); +/* + if ( SetSingleStringCommand( command, console_audio_stream_path, PATH_MAX ) ) { + + // process file name and use current workdir + strcpy( console_audio_stream_path, SubstCurWorkDir( console_audio_stream_path ) ); + } +*/ + // recognize always (implicitly reserves domain) + return TRUE; +} + + +// set file path for intro audio stream --------------------------------------- +// +PRIVATE +int Cmd_SetPathAudioStreamIntro( char *command ) +{ + ASSERT( command != NULL ); + HANDLE_COMMAND_DOMAIN( command ); +/* + if ( SetSingleStringCommand( command, intro_stream_name, PATH_MAX ) ) { + + // process file name and use current workdir + strcpy( intro_stream_name, SubstCurWorkDir( intro_stream_name ) ); + } +*/ + // recognize always (implicitly reserves domain) + return TRUE; +} + + +// set file path for menu audio stream ---------------------------------------- +// +PRIVATE +int Cmd_SetPathAudioStreamMenu( char *command ) +{ + ASSERT( command != NULL ); + HANDLE_COMMAND_DOMAIN( command ); + +/* + if ( SetSingleStringCommand( command, menu_stream_name, PATH_MAX ) ) { + + // process file name and use current workdir + strcpy( menu_stream_name, SubstCurWorkDir( menu_stream_name ) ); + } +*/ + + // recognize always (implicitly reserves domain) + return TRUE; +} + + +// init console talk mode ----------------------------------------------------- +// +PRIVATE +void InitTalkMode() +{ + ASSERT( con_in_talk_mode ); + + // clear screen, set cursor to screen-bottom line + ClearConScreen(); + + // create separator line + CreateSeparatorLine( con_bottom ); + + // save number of line right below separator line + CON_AddLineFeed(); + CON_DisableLineFeed(); + con_talk_line = con_bottom; +} + + +// command "cls" -------------------------------------------------------------- +// +PRIVATE +void Cmd_CLS() +{ + if ( con_in_talk_mode ) { + + // reactivate talkmode + InitTalkMode(); + + } else { + wclear( g_curses_out_win ); + } +} + + +// command "talk" (toggle talk mode on and off) ------------------------------- +// +PRIVATE +void Cmd_TALK() +{ + // toggle talk mode + con_in_talk_mode = !con_in_talk_mode; + + if ( con_in_talk_mode ) { + // talkmode init clears screen + InitTalkMode(); + } else { + // clear screen + Cmd_CLS(); + } +} + + +// command "quit" ------------------------------------------------------------- +// +PRIVATE +void Cmd_QUIT() +{ + TheServer->SetQuitFlag(); +} + + +// command "hex" -------------------------------------------------------------- +// +PRIVATE +void Cmd_HEX() +{ + int_print_base = "%x"; + int_calc_base = 16; + CON_AddLine( base_set_to_hex ); + strcpy( base_str + BASE_INSERT_POS, base_hex ); +} + + +// command "dec" -------------------------------------------------------------- +// +PRIVATE +void Cmd_DEC() +{ + int_print_base = "%d"; + int_calc_base = 10; + CON_AddLine( base_set_to_dec ); + strcpy( base_str + BASE_INSERT_POS, base_dec ); +} + + +// command "oct" -------------------------------------------------------------- +// +PRIVATE +void Cmd_OCT() +{ + int_print_base = "%o"; + int_calc_base = 8; + CON_AddLine( base_set_to_oct ); + strcpy( base_str + BASE_INSERT_POS, base_oct ); +} + + +// command "base" ------------------------------------------------------------- +// +PRIVATE +void Cmd_BASE() +{ + CON_AddLine( base_str ); +} + +// close network connection ("disconnect") ------------------------------------ +// +PRIVATE +void Cmd_DISCONNECT() +{ +} + + +// commands corresponding to functions with no parameters --------------------- +// +struct cmd_noparam_s { + + int commandid; + void (*commandfunc)(void); +}; + +cmd_noparam_s cmd_noparam[] = { + + //{ CM_REPINFO, Cmd_QueryReplayInfo }, + //{ CM_REPSTOP, Cmd_StopBatchReplay }, + { CM_CLS, Cmd_CLS }, + { CM_CLEAR, Cmd_CLS }, + { CM_QUIT, Cmd_QUIT }, + { CM_EXIT, Cmd_QUIT }, + { CM_HEX, Cmd_HEX }, + { CM_DEC, Cmd_DEC }, + { CM_OCT, Cmd_OCT }, + { CM_BASE, Cmd_BASE }, + { CM_OBJECTCLEAR, Cmd_OBJECTCLEAR }, + { CM_OBJECTCOUNT, Cmd_OBJECTCOUNT }, + { CM_SHIPS, Cmd_ShipInfo }, + { CM_LISTCLASSES, Cmd_ListClasses }, + { CM_LISTTYPES, Cmd_ListTypes }, + //{ CM_LISTTEXTMACS, Cmd_ListSayMacros }, + //{ CM_LISTBINDINGS, Cmd_ListKeyBindings }, + //{ CM_SETORIGIN, Cmd_SetShipOrigin }, + { CM_SHOWPOSITION, Cmd_SHOWPOSITION }, + //{ CM_CLOSE, Cmd_CloseOutputBatch }, + //{ CM_LISTGAMEFUNCKEYS, Cmd_ListKeyFunctions }, + { CM_DISCONNECT, Cmd_DISCONNECT }, + //{ CM_TALKMODE, Cmd_TALK }, + { CM_RESCAN, Cmd_RescanExternalCommands }, + //{ CM_LISTDEMOS, Cmd_ListBinaryDemos }, +}; + +#define NUM_CMDS_NOPARAM CALC_NUM_ARRAY_ENTRIES( cmd_noparam ) + + +// commands corresponding to functions with no parameters --------------------- +// +int CheckCmdsNoParam( char *command ) +{ + //NOTE: + // this function returns TRUE if a valid command + // has been detected and executed. it returns + // FALSE if no valid command has been detected + // and the command string therefore needs + // further processing by the main dispatcher. + + ASSERT( command != NULL ); + + // check for commands in "no param" table + for ( unsigned int tid = 0; tid < NUM_CMDS_NOPARAM; tid++ ) { + + const char *cmdstr = CMSTR( cmd_noparam[ tid ].commandid ); + int cmdlen = CMLEN( cmd_noparam[ tid ].commandid ); + + if ( strncmp( command, cmdstr, cmdlen ) == 0 ) { + + // eat trailing whitespace + char *whsp = command + cmdlen; + for ( ; *whsp; whsp++ ) + if ( *whsp != ' ' ) + break; + if ( *whsp == 0 ) { + // only whitespace -> command valid + (*cmd_noparam[ tid ].commandfunc)(); + return TRUE; + } else if ( command[ cmdlen ] == ' ' ) { + // excess parameters + CON_AddLine( dont_use_params ); + return TRUE; + } + } + } + + return FALSE; +} + + +// commands corresponding to functions with an arbitrary string parameter ----- +// +struct cmd_customstring_s { + + int commandid; + int (*commandfunc)(char*); +}; + +cmd_customstring_s cmd_customstring[] = { + + { CM_BUILD, Cmd_BuildInfo }, + //{ CM_PATH_ANIM_INTRO, Cmd_SetPathAnimIntro }, + //{ CM_PATH_ASTREAM_INTRO, Cmd_SetPathAudioStreamIntro }, + //{ CM_PATH_ASTREAM_MENU, Cmd_SetPathAudioStreamMenu }, + //{ CM_PATH_ASTREAM, Cmd_SetPathAudioStreams }, + { CM_WORKINGDIRECTORY, Cmd_SetPathWorkingDirectory }, + { CM_LISTINTCOMMANDS, Cmd_ListIntCommands }, + { CM_LISTSTDCOMMANDS, Cmd_ListStdCommands }, + { CM_LISTEXTCOMMS, Cmd_ListExternalCommands }, + { CM_DISPLAY, Cmd_DisplayText }, + { CM_CAT, Cmd_CatExternalCommands }, + //{ CM_GAMELOOPBATCH, Cmd_SetGameLoopBatchName }, ???? + //{ CM_SAY, Cmd_SayText }, + { CM_LISTDATA, Cmd_ListDataTable }, + { CM_WRITESTRING, Cmd_WriteText }, + { CM_CREATE, Cmd_Create }, + { CM_OPEN, Cmd_Open }, + { CM_RECDEM, Cmd_Recdem }, + { CM_RECORD, Cmd_Record }, + { CM_APPEND, Cmd_Append }, + //{ CM_PLAYDEMO, Cmd_PlayBinaryDemoFile }, + { CM_LOAD, Cmd_ExecLoadCommand }, +}; + +#define NUM_CMDS_CUSTOMSTRING CALC_NUM_ARRAY_ENTRIES( cmd_customstring ) + + +// commands corresponding to functions taking an arbitrary string parameter --- +// +int CheckCmdsCustomString( char *command ) +{ + ASSERT( command != NULL ); + + //NOTE: + // this function returns TRUE if a valid command + // has been detected and executed. it returns + // FALSE if no valid command has been detected + // and the command string therefore needs + // further processing by the main dispatcher. + + //NOTE: + // a space as delimiter behind a command is not + // enforced by this function. that is, the supplied + // parsing functions can grab an entire domain + // (set of commands starting with the same characters). + // but this also means they have to ensure the delimiter + // is indeed there if there should be only one command. + + //NOTE: + // due to the semantics of this function and most parsing + // functions it calls, most "custom string" commands reserve + // an entire domain. that is, after this function no + // commands starting with the same characters as a + // "custom string" command will be recognized. + // this behavior also depends on HANDLE_COMMAND_DOMAIN(). + + // check for commands in "custom string" table + for ( unsigned int tid = 0; tid < NUM_CMDS_CUSTOMSTRING; tid++ ) { + + const char *cmdstr = CMSTR( cmd_customstring[ tid ].commandid ); + int cmdlen = CMLEN( cmd_customstring[ tid ].commandid ); + + if ( strncmp( command, cmdstr, cmdlen ) == 0 ) { + + ASSERT( cmd_customstring[ tid ].commandfunc != NULL ); + return (*cmd_customstring[ tid ].commandfunc)( command + cmdlen ); + } + } + + return FALSE; +} + + +// user command handling ------------------------------------------------------ +// +PRIVATE user_command_s user_commands_default[ 32 ]; +PUBLIC user_command_s* user_commands = user_commands_default; +PUBLIC int num_user_commands = 0; +PRIVATE int max_user_commands = 32; + + +// check user commands -------------------------------------------------------- +// +int CheckCmdsUserDefined( char *command ) +{ + ASSERT( command != NULL ); + + //NOTE: + // the semantics of this function is basically + // the same as for CheckCmdsCustomString(). + + //NOTE: + // this function will be called very early in + // the sequence of command comparsions. thus, + // it can override most other commands. the + // callback functions have to be very careful + // not to block entire domains without any reason. + + // check for commands in user commands table + for ( int cid = 0; cid < num_user_commands; cid++ ) { + + const char *cmdstr = user_commands[ cid ].command; + int cmdlen = user_commands[ cid ].commlen; + + if ( strncmp( command, cmdstr, cmdlen ) == 0 ) { + + ASSERT( user_commands[ cid ].execute != NULL ); + return (*user_commands[ cid ].execute)( command + cmdlen ); + } + } + + return FALSE; +} + + +// register a new user-defined command ---------------------------------------- +// +int CON_RegisterUserCommand( user_command_s *regcom ) +{ + //NOTE: + //CAVEAT: + // the supplied command string is not copied + // by this function. thus, the caller MUST ENSURE + // that this string is available indefinitely. + // (e.g., allocated statically.) + + //NOTE: + // the commlen field need not be valid, it will be + // set by this function. (in the original struct!) + + ASSERT( regcom != NULL ); + ASSERT( regcom->command != NULL ); + ASSERT( regcom->execute != NULL ); + ASSERT( regcom->numparams >= 0 ); + ASSERT( num_user_commands <= max_user_commands ); + + // expand table memory if already used up + if ( num_user_commands == max_user_commands ) { + + // expand exponentially + int newtabsize = max_user_commands * 2; + + // alloc new table + user_command_s *newlist = (user_command_s *) ALLOCMEM( sizeof( user_command_s ) * newtabsize ); + if ( newlist == NULL ) { + ASSERT( 0 ); + return FALSE; + } + + // set new size + max_user_commands = newtabsize; + + // move old table + memcpy( newlist, user_commands, sizeof( user_command_s ) * num_user_commands ); + if ( user_commands != user_commands_default ) + FREEMEM( user_commands ); + user_commands = newlist; + } + + // append new command + regcom->commlen = strlen( regcom->command ); + ASSERT( num_user_commands < max_user_commands ); + user_commands[ num_user_commands++ ] = *regcom; + + return TRUE; +} + +// replace the entry for an already registered user-defined command ----------- +// +int CON_ReplaceUserCommand( user_command_s* repcom ) +{ + //NOTE: + //CAVEAT: + // the supplied command string is not copied + // by this function. thus, the caller MUST ENSURE + // that this string is available indefinitely. + // (e.g., allocated statically.) + + //NOTE: + // the commlen field need not be valid, it will be + // set by this function. (in the original struct!) + + ASSERT( repcom != NULL ); + ASSERT( repcom->command != NULL ); + ASSERT( repcom->execute != NULL ); + ASSERT( repcom->numparams >= 0 ); + + for( int user_command_index = 0; user_command_index < num_user_commands; user_command_index++ ) { + + // check for equal command string + if( stricmp( user_commands[ user_command_index ].command , repcom->command ) == 0 ) { + repcom->commlen = strlen( repcom->command ); + user_commands[ user_command_index ] = *repcom; + + return TRUE; + } + } + + return FALSE; +} + + +// module registration function ----------------------------------------------- +// +REGISTER_MODULE( CON_COM_SV ) +{ + +#ifdef PARSEC_DEBUG + + // register "heap" command + user_command_s regcom; + regcom.command = "heap"; + regcom.numparams = 0; + regcom.execute = Cmd_HEAP; + regcom.statedump = NULL; + CON_RegisterUserCommand( ®com ); + +#endif // PARSEC_DEBUG + +} + + + diff --git a/src/parsec_server/con_ext_sv.cpp b/src/parsec_server/con_ext_sv.cpp new file mode 100755 index 0000000..c3c556d --- /dev/null +++ b/src/parsec_server/con_ext_sv.cpp @@ -0,0 +1,1193 @@ +/* + * PARSEC - Server External Commands + * + * $Author: uberlinuxguy $ - $Date: 2004/09/15 12:25:44 $ + * + * Orginally written by: + * Copyright (c) Clemens Beer 2001 + * Copyright (c) Markus Hadwiger 1996-2001 + * + * 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 2 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +// C library +#include +#include +#include +#include +#include + +// compilation flags/debug support +#include "config.h" +#include "debug.h" + +// general definitions +#include "general.h" +#include "objstruc.h" + +// global externals +#include "globals.h" + +// local module header +#include "con_ext_sv.h" + +// proprietary module headers +//#include "con_act.h" +#include "con_aux_sv.h" +#include "con_list_sv.h" +#include "con_main_sv.h" +#include "con_std_sv.h" +#include "con_vald.h" // shared ! +//#include "e_demo.h" +//#include "e_record.h" +//#include "e_replay.h" +#include "sys_file.h" +#include "sys_path.h" + + + +// maximum depth of recursion in command batch files +#define MAX_BATCH_REC_DEPTH 16 + +// special eof needed in package console scripts +#define PACKAGE_CON_EOF ";eof" +#define PACKAGE_CON_EOF_LEN 4 + +// generic string paste area +#define PASTE_STR_LEN 255 +static char paste_str[ PASTE_STR_LEN + 1 ]; + +// string constants +static char con_extension[] = CON_FILE_EXTENSION; +static char invalid_batch_name[]= "invalid name specifier."; +static char recursion_canceled[]= "command canceled due to recursion."; +static char recursion_maxdepth[]= "maximum recursion depth reached."; +static char replaying_script[] = "replay in progress (script)."; +static char replaying_binary[] = "replay in progress (binary)."; +static char no_replay[] = "no replay in progress."; +static char stopped_replay[] = "replay has been stopped."; +static char record_disallowed[] = "recording not allowed (object camera is active)."; + +static char con_file_wldcard1[] = "*" CON_FILE_EXTENSION; +static char con_file_wldcard2[] = REFCON_COMMANDS_DIR "*" CON_FILE_EXTENSION; +static char con_file_wldcard3[] = STDCON_COMMANDS_DIR "*" CON_FILE_EXTENSION; +static char con_file_wldcard4[] = RECORD_COMMANDS_DIR "*" CON_FILE_EXTENSION; + +// name of batch command file to execute on every gameloop start +char gameloop_start_script[ PATH_MAX + 1 ] = ""; + +// list of external commands +char external_commands[ MAX_EXTERNAL_COMMANDS + 1 ][ COMMAND_NAME_ALLOC_LEN + 1 ]; +int external_command_types[ MAX_EXTERNAL_COMMANDS + 1 ]; +int num_external_commands = 0; + +// external batch execution vars +int processing_batch = 0; // flag that commands are called from batch +int idle_reclevel = 0; // level of recursion idle wait stalled execution on +int rec_depth = 0; // current level of recursion + +// action commands not allowed? +int preempt_action_commands = FALSE; + +// batch execution recursive call stack +static int extcom_on_level[ MAX_BATCH_REC_DEPTH + 1 ]; +static FILE *fp_for_level[ MAX_BATCH_REC_DEPTH + 1 ]; + +// log file (created command batch) +FILE *log_fp; +char log_name[ COMMAND_NAME_ALLOC_LEN + 1 ]; +int log_commands = 0; + +// recording file +static char record_name[ COMMAND_NAME_ALLOC_LEN + 1 ]; + +// packet recording/replay file names +char packet_record_name[ COMMAND_NAME_ALLOC_LEN + 1 ]; +char packet_replay_name[ COMMAND_NAME_ALLOC_LEN + 1 ]; + +// single command line +static char com_line[ MAX_CONSOLE_LINE_LENGTH + 1 ]; + +// cat feature variables +static char cat_name[ MAX_CONSOLE_LINE_LENGTH + 1 ]; +static int cat_pos; + +// current active mod name +PUBLIC char* mod_names[ MAX_REGISTERED_MODS ]; +PUBLIC int mod_numnames = 0; +PUBLIC int mod_override = FALSE; + + +// acquire scripts located in mod directories --------------------------------- +// +PRIVATE +void AcquireModScripts() +{ + for ( int mod = 0; mod < mod_numnames; mod++ ) { + + char *path = (char *) ALLOCMEM( strlen( mod_names[ mod ] ) + strlen( con_file_wldcard1 ) + 2 ); + if ( path == NULL ) { + OUTOFMEM( 0 ); + } + + strcpy( path, mod_names[ mod ] ); + strcat( path, "/" ); + strcat( path, con_file_wldcard1 ); + + char *npath = SYSs_ProcessPathString( path ); + SYSs_AcquireScriptPath( npath, COMTYPE_MODIFICATION, mod_names[ mod ] ); + + FREEMEM( path ); + } +} + + +// build list of externally available commands -------------------------------- +// +void BuildExternalCommandList() +{ + //NOTE: + // the sequence of paths scanned in this function mostly determines the + // display order of console scripts (ls command, tab completion, ...). + // the actual precedence of scripts is determined by the search order + // in OpenScript(). for consistency, the two orders should be the same. + + num_external_commands = 0; + + SYS_AcquirePackageScripts( COMTYPE_PACKAGE ); + + if ( mod_override ) { + AcquireModScripts(); + } + + SYSs_AcquireScriptPath( con_file_wldcard1, COMTYPE_ROOT, NULL ); + SYSs_AcquireScriptPath( con_file_wldcard2, COMTYPE_REFERENCE, NULL ); + SYSs_AcquireScriptPath( con_file_wldcard3, COMTYPE_STANDARD, NULL ); + SYSs_AcquireScriptPath( con_file_wldcard4, COMTYPE_RECORDING, NULL ); + + if ( !mod_override ) { + AcquireModScripts(); + } +} + + +// check if string is valid external command ---------------------------------- +// +int CheckExternalCommand( char *com ) +{ + ASSERT( com != NULL ); + + //NOTE: + // command script directories are only scanned once. therefore, + // new commands copied into a directory while the game is still + // running will not be noticed until next startup or explicit + // rescanning via the "rescan" command. + + // to ensure scripts with explicitly specified paths work + com = SYSs_ProcessPathString( com ); + + // scan list in memory (no directory rescanning!!) + int cid = -1; + for ( int eid = 0; eid < num_external_commands; eid++ ) { + ASSERT( external_commands[ eid ] != NULL ); + if ( stricmp( external_commands[ eid ], com ) == 0 ) { + cid = eid; + break; + } + } + + // return command number + 1 (thus 0 means command is invalid) + return ( cid + 1 ); +} + + +// insert command into log file (command batch) ------------------------------- +// +int InsertCommandLog( char *command ) +{ + ASSERT( command != NULL ); + + if ( log_commands && ( strcmp( command, CMSTR( CM_CLOSE ) ) != 0 ) ) { + // append command to currently open logfile + fprintf( log_fp, "%s\n", command ); + return TRUE; + } + + return FALSE; +} + + +// search all console script paths and open batch if it exists ---------------- +// +PRIVATE +FILE *OpenScript( char *script ) +{ + ASSERT( script != NULL ); + + //NOTE: + // the sequence of paths scanned in this function determines the + // precedence of console scripts of the same name but located in + // different directories. + + //NOTE: + // the path search sequence is: + // 1. data package + // 2. root (local) directory + // 3. reference directory (refs) + // 4. standard directory (cons) + // 5. recording directory (recs) + + //NOTE: + // to avoid inconsistencies the search order in E_RECORD::LoadPacket() + // and E_DEMO::DEMO_BinaryOpenDemo() should be consistent + // with the search order used here. + + FILE *fp = NULL; + + strcpy( paste_str, script ); + strcat( paste_str, con_extension ); + + // to ensure scripts with explicitly specified paths work + char *path = SYSs_ProcessPathString( paste_str ); + + if ( SV_PACKAGE_SCRIPTS ) { + + // try to read from package first + if ( ( fp = SYS_fopen( path, "r" ) ) != NULL ) { + return fp; + } + } + + // search root (local) directory + if ( ( fp = fopen( path, "r" ) ) != NULL ) { + return fp; + } + + strcpy( paste_str, REFCON_COMMANDS_DIR ); + strcat( paste_str, script ); + strcat( paste_str, con_extension ); + + // search reference directory (refs) + if ( ( fp = fopen( paste_str, "r" ) ) != NULL ) { + return fp; + } + + strcpy( paste_str, STDCON_COMMANDS_DIR ); + strcat( paste_str, script ); + strcat( paste_str, con_extension ); + + // search standard directory (cons) + if ( ( fp = fopen( paste_str, "r" ) ) != NULL ) { + return fp; + } + + strcpy( paste_str, RECORD_COMMANDS_DIR ); + strcat( paste_str, script ); + strcat( paste_str, con_extension ); + + // search recording directory (recs) + return fopen( paste_str, "r" ); +} + + +// display content of command batch file -------------------------------------- +// +PRIVATE +void CatExternalCommands_ctd() +{ + int i = 0; + + FILE *fp = OpenScript( cat_name ); + + if ( fp != NULL ) { + + SYS_fseek( fp, cat_pos, SEEK_SET ); + + int packeof = 0; + while ( SYS_fgets( com_line, MAX_CONSOLE_LINE_LENGTH, fp ) != NULL ) { + + // check special package eof + if ( strncmp( com_line, PACKAGE_CON_EOF, PACKAGE_CON_EOF_LEN ) == 0 ) { + packeof = 1; + break; + } + + ProcessExternalLine( com_line ); + CON_AddLine( com_line ); + if ( ++i >= cur_vis_conlines - 1 ) { + break; + } + } + + if ( packeof || SYS_feof( fp ) ) { + CON_ListEndPrompt(); + } else { + CON_ListCtdPrompt(); + cat_pos = SYS_ftell( fp ); + } + + SYS_fclose( fp ); + } +} + + +// display content of command batch file (command "cat") ---------------------- +// +int Cmd_CatExternalCommands( char *cstr ) +{ + ASSERT( cstr != NULL ); + HANDLE_COMMAND_DOMAIN_SEP( cstr ); + + char *name = strtok( cstr, " " ); + + if ( ( name == NULL ) || ( strtok( NULL, " " ) != NULL ) ) { + CON_AddLine( "syntax: cat