// ship collided with EMP --------------------------------------------------- // void G_CollDet::_CollisionResponse_EmpShip( Emp *curemp ) { ASSERT( curemp != NULL ); ASSERT( cur_ship != NULL ); int hitpoints = curemp->damage; if ( ( hitpoints -= cur_ship->MegaShieldAbsorption ) < 0 ) { hitpoints = 0; } // apply damage if ( cur_ship->CurDamage <= cur_ship->MaxDamage ) { MSGOUT("Hitpoints deduction is %d", hitpoints); MSGOUT("Damage Calc Ref Frames is %d",TheSimulator->GetThisFrameRefFrames()*2); cur_ship->CurDamageFrac += (TheSimulator->GetThisFrameRefFrames()*2) * hitpoints; MSGOUT("Damage Fractional is %d",cur_ship->CurDamageFrac); cur_ship->CurDamage += cur_ship->CurDamageFrac >> 16; MSGOUT("Doing %d damage to ship", cur_ship->CurDamageFrac >> 16); cur_ship->CurDamageFrac &= 0xffff; // new less confusing shit... //cur_ship->CurDamage += hitpoints; }
// append a RE list to the FIFO ---------------------------------------------- // int NET_Stream::AppendToReliableFIFO( E_REList* pREList ) { ASSERT( pREList != NULL ); //MSGOUT( "AppendToReliableFIFO(): " ); //pREList->Dump(); if ( pREList->GetSize() == 0 ) { ASSERT( FALSE ); return FALSE; } if ( !m_EnableReliable ) { ASSERT( FALSE ); return FALSE; } // check whether the new append would cause the FIFO to overflow int nNextWritePos = _FIFO_GetNextWritePos(); StreamFIFOEntry_s* pEntry = &m_FIFOEntries[ nNextWritePos ]; if ( pEntry->m_pREList != NULL ) { DBGTXT( MSGOUT("NET_Stream::AppendToReliableFIFO(): FIFO overflow." ); for( int nEntry = 0; nEntry < MAX_NUM_RELIABLE_BACKLOG; nEntry++ ) { MSGOUT( "================================\n" ); MSGOUT( "FIFO: %d\n", nEntry ); m_FIFOEntries[ nEntry ].m_pREList->Dump(); MSGOUT( "================================\n" ); } );
// init sound system and sound hardware --------------------------------------- // int AUDs_InitSoundSys() { if (SDL_Init(SDL_INIT_AUDIO) < 0) { MSGOUT("Failed to open audio.\n"); SoundDisabled = TRUE; return FALSE; } if (Mix_OpenAudio(44100, AUDIO_S16, 2, 4096) == -1) { MSGOUT("Could not open mixer.\n%s\n",Mix_GetError()); SoundDisabled = TRUE; return FALSE; } Mix_AllocateChannels(32); Mix_Volume(-1, MIX_MAX_VOLUME); AUDs_LoadAllSoundEffects(); AUD_BackGroundPlayer_Init(1); //Mix_HookMusicFinished(AUDs_MusicFinished); MSGOUT("Sound Init Done\n"); snd_init_done = TRUE; return TRUE; }
// register additional data package ------------------------------------------- // PRIVATE int SLm_RegisterPackage( char **packagename ) { char *name = packagename[ 0 ]; if ( !SYS_RegisterPackage( name, 0, NULL ) ) { MSGOUT( "CLI error: package registration failed (%s).\n", name ); MSGOUT( "CLI error: continuing without package.\n" ); } return TRUE; }
// ensure a client is not connected ------------------------------------------- // int E_ConnManager::_EnsureClientIsDisconnected( E_ClientConnectInfo* pClientConnectInfo ) { ASSERT( pClientConnectInfo != NULL ); ASSERT( pClientConnectInfo->m_szHostName != NULL ); ASSERT( &pClientConnectInfo->m_node != NULL ); ASSERT( pClientConnectInfo->m_szName != NULL ); ASSERT( pClientConnectInfo->m_szOSLine != NULL ); // check for duplicate connects from same node for( int nSlot = 0; nSlot < MAX_NUM_CLIENTS; nSlot++ ) { E_ClientInfo* pClientInfo = &m_ClientInfos[ nSlot ]; if ( !pClientInfo->IsSlotFree() ) { if ( NODE_Compare( &pClientInfo->m_node, &pClientConnectInfo->m_node ) == NODECMP_EQUAL ) { MSGOUT( "Removing (possibly) dead client %s", NODE_Print( &pClientConnectInfo->m_node ) ); // disconnect the client DisconnectClient( nSlot ); } } } return TRUE; }
// init SDL input -------------------------------------------------------------- // void INPs_InitGeneral() { int rc = SDL_Init(SDL_INIT_EVERYTHING); // by the time we get here, we should want everything else up if(rc < 0){ MSGOUT("Error: SDL_Init() error in INPs_InitGeneral() in inp_sdl.cpp"); return; } // TODO: import sdl_video_init_done from vsdl.h //if ( sdl_video_init_done ) // return; // events we want to receive // XXX:Probably not used. // main window attributes // XXX:Probably not used. // create splash screen //splash_screen_valid = CreateSplashPixmap(); // fill window with splash screen image //DrawSplashScreen(); // install signal handlers // disabled because not cross-platform and probably not necessary //ISDLm_InstallSignalHandlers(); }
// join game (enter game from entry mode in already allocated slot) ----------- // int NETs_Join() { ASSERT( NetConnected && !NetJoined ); ASSERT( LocalPlayerId >= 0 && LocalPlayerId < MAX_NET_PROTO_PLAYERS ); ASSERT( Player_Status[ LocalPlayerId ] == PLAYER_CONNECTED ); { // update player status Player_Status[ LocalPlayerId ] = PLAYER_JOINED; Player_Ship [ LocalPlayerId ] = MyShip; Player_ShipId[ LocalPlayerId ] = SHIPID_LOCALPLAYER; // set global flags NetJoined = TRUE; //HaveFullPlayerState = FALSE; //FIXME Put this back one day when the server actually verifies this stuff (which it currently doesn't) //but for now this fixes/works around stargate jump sync issues HaveFullPlayerState = TRUE; // open stargate if ( !AUX_DISABLE_LOCAL_STARGATE ) { SFX_CreateStargate( MyShip ); } // record join Record_Join(); } // store the message # that contains this state change g_dwLastStatusChangeMsg = ServerStream.GetNextOutMessageId(); // send join message to server DBGTXT( MSGOUT( "sending join message to server." ); );
// check for a client namechange ---------------------------------------------- // int E_ConnManager::CheckNameChange( node_t* clientnode, char* newplayername ) { ASSERT( clientnode != NULL ); ASSERT( newplayername != NULL ); // find the slot int nSlot = _FindSlotWithNode( clientnode ); // we could find the slot if( nSlot != -1 ) { MSGOUT( "client %s wants to be renamed to %s\n", NODE_Print( &m_ClientInfos[ nSlot ].m_node ), newplayername ); // only check for name collision if not alone if ( m_nNumConnected > 1 ) { // check all the other connected slots for the same name for( int nOtherSlot = 0; nOtherSlot < MAX_NUM_CLIENTS; nOtherSlot++ ) { // check for different slot if ( nSlot != nOtherSlot ) { // check whether slot is free if( !m_ClientInfos[ nOtherSlot ].IsSlotFree() ) { // check whether this name is already taken if( strcmp( newplayername, m_ClientInfos[ nOtherSlot ].m_szName) == 0 ) { // name already taken ThePacketHandler->SendNameChangeRepsponse( NAMECHANGE_ALREADY_TAKEN, clientnode, nSlot ); return FALSE; } } } } } // namechange OK ThePacketHandler->SendNameChangeRepsponse( NAMECHANGE_OK, clientnode, nSlot ); // change the name _ChangeClientName( nSlot, newplayername ); // mark the client alive m_ClientInfos[ nSlot ].MarkAlive(); // send namechange notifications to the other clients _NotifyClientNameChange( nSlot ); return TRUE; } else { // client is not connected ThePacketHandler->SendNameChangeRepsponse( NAMECHANGE_NOT_CONNECTED, clientnode, nSlot ); return FALSE; } }
// join game (enter game from entry mode in already allocated slot) ----------- // int NETs_Join() { ASSERT( NetConnected && !NetJoined ); ASSERT( LocalPlayerId >= 0 && LocalPlayerId < MAX_NET_PROTO_PLAYERS ); ASSERT( Player_Status[ LocalPlayerId ] == PLAYER_CONNECTED ); { // update player status Player_Status[ LocalPlayerId ] = PLAYER_JOINED; Player_Ship [ LocalPlayerId ] = MyShip; Player_ShipId[ LocalPlayerId ] = SHIPID_LOCALPLAYER; // set global flags NetJoined = TRUE; HaveFullPlayerState = FALSE; // open stargate if ( !AUX_DISABLE_LOCAL_STARGATE ) { SFX_CreateStargate( MyShip ); } // record join Record_Join(); } // store the message # that contains this state change g_dwLastStatusChangeMsg = ServerStream.GetNextOutMessageId(); // send join message to server DBGTXT( MSGOUT( "sending join message to server." ); );
// walk list of laser objects and advance them -------------------------------- // PRIVATE void WalkLaserObjects() { ASSERT( LaserObjects != NULL ); GenObject *precnode = LaserObjects; GenObject *walkshots = LaserObjects->NextObj; // walk all lasers while ( walkshots != NULL ) { ASSERT( OBJECT_TYPE_LASER( walkshots ) ); LaserObject *laserpo = (LaserObject *) walkshots; laserpo->LifeTimeCount -= CurScreenRefFrames; if ( laserpo->LifeTimeCount <= 0 ) { #ifndef DONT_RESET_SHOTCOUNTER NumShots--; #endif NET_RmEvKillObject( laserpo->HostObjNumber, LASER_LIST ); #ifdef LINKED_PROTOCOL_GAMESERVER #ifdef INTERNAL_VERSION if ( NET_ConnectedGMSV() ) { ASSERT( FALSE ); MSGOUT( "OBJ_Ani::WalkLaserObjects(): predicted freeing of laser object" ); } #endif // INTERNAL_VERSION #endif // LINKED_PROTOCOL_GAMESERVER ASSERT( walkshots != NULL ); precnode->NextObj = walkshots->NextObj; FreeObjectMem( walkshots ); walkshots = precnode->NextObj; continue; } else { Vector3 tempspeed; tempspeed.X = laserpo->DirectionVec.X * CurScreenRefFrames; tempspeed.Y = laserpo->DirectionVec.Y * CurScreenRefFrames; tempspeed.Z = laserpo->DirectionVec.Z * CurScreenRefFrames; laserpo->PrevPosition.X = laserpo->ObjPosition[ 0 ][ 3 ]; laserpo->PrevPosition.Y = laserpo->ObjPosition[ 1 ][ 3 ]; laserpo->PrevPosition.Z = laserpo->ObjPosition[ 2 ][ 3 ]; laserpo->ObjPosition[ 0 ][ 3 ] += tempspeed.X; laserpo->ObjPosition[ 1 ][ 3 ] += tempspeed.Y; laserpo->ObjPosition[ 2 ][ 3 ] += tempspeed.Z; } precnode = walkshots; walkshots = walkshots->NextObj; } }
// add new line to console ---------------------------------------------------- // PUBLIC void CON_AddLine( const char *text ) { ASSERT( text != NULL ); // normal text output MSGOUT( text ); }
// add new message to console (preserve current input) ------------------------ // PUBLIC void CON_AddMessage( const char *text ) { ASSERT( text != NULL ); // normal message output MSGOUT( text ); }
// read palette files into buffer --------------------------------------------- // PRIVATE void ReadPalettes() { // exit if nothing to read if ( NumLoadedPalettes == 0 ) PANIC( "no palette defined." ); if ( ( PaletteMem = (char *) ALLOCMEM( PALETTE_SIZE * NumLoadedPalettes ) ) == NULL ) OUTOFMEM( no_palette_mem ); if ( display_info ) { MSGPUT( "Loading palettes" ); if ( show_palettes_loaded ) { MSGOUT( ":\n" ); } else { MSGPUT( "..." ); } } // load all palettes size_t readofs = 0; for ( int pid = 0; pid < NumLoadedPalettes; pid++ ) { if ( display_info && !show_palettes_loaded ) MSGPUT( "." ); FILE *fp = SYS_fopen( palette_fnames[ pid ], "rb" ); if ( fp == NULL ) FERROR( palette_not_found, palette_fnames[ pid ] ); if ( display_info && show_palettes_loaded ) { MSGOUT( "loading \"%s\" (palette)\n", palette_fnames[ pid ] ); } size_t bytesread = SYS_fread( PaletteMem + readofs, 1, PALETTE_SIZE, fp ); if ( bytesread != PALETTE_SIZE ) FERROR( palette_readerror, palette_fnames[ pid ] ); readofs += PALETTE_SIZE; SYS_fclose( fp ); } if ( display_info ) { MSGOUT( "done.\n" ); } }
// resolve a hostname using the DNS service ----------------------------------- // int NET_ResolveHostName( const char* hostname, char* ipaddress, node_t* node ) { ASSERT( hostname != NULL ); if ( isdigit( hostname[ 0 ] ) ) { // hostname is assumed to be an ip address -> just convert to binary representation if ( node != NULL ) { inet_aton( hostname, (in_addr*)node ); } if ( ipaddress != NULL ) { strncpy( ipaddress, hostname, MAX_IPADDR_LEN ); ipaddress[ MAX_IPADDR_LEN ] = 0; } return TRUE; } hostent *hptr = gethostbyname( hostname ); if ( hptr == NULL ) { MSGOUT( "NET_ResolveHostName(): DNS error: %s %s.", hostname, hstrerror( h_errno ) ); return FALSE; } if ( hptr->h_addrtype == AF_INET ) { char **pptr = hptr->h_addr_list; if ( *pptr != NULL ) { // store node ? if ( node != NULL ) { memcpy( node, *pptr, IP_ADR_LENGTH ); } // store numeric IP adress string if ( ipaddress != NULL ) { inet_ntop( hptr->h_addrtype, *pptr, ipaddress, MAX_IPADDR_LEN + 1 ); } return TRUE; } } else { MSGOUT( "NET_ResolveHostName(): illegal address type in DNS entry." ); } return FALSE; }
// initialize joystick device ------------------------------------------------- // void ISDL_JoyInitHandler() { SDL_InitSubSystem(SDL_INIT_JOYSTICK); isdl_nJoystickFound = SDL_NumJoysticks(); MSGOUT("isdl_joy: Found %d joysticks.\n", isdl_nJoystickFound); if(isdl_nJoystickFound > 0) { //TODO: Implement support for more than one stick when we have more flexible input layer stuff MSGOUT("isdl_joy: ... but we don't care, because Parsec only has one JoyState\n"); isdl_joyHandle = SDL_JoystickOpen(0); isdl_NumAxes = SDL_JoystickNumAxes(isdl_joyHandle); isdl_NumButtons = SDL_JoystickNumButtons(isdl_joyHandle); isdl_NumButtons = isdl_NumButtons > 32 ? 32 : isdl_NumButtons; MSGOUT("isdl_joy: Joystick%d has %d axes and %d buttons\n", 0, isdl_NumAxes, isdl_NumButtons); QueryJoystick = TRUE; JoystickDisabled = FALSE; } }
// register mod which overrides internal packages ----------------------------- // PRIVATE int SLm_RegisterModForce( char **modname ) { char *name = modname[ 0 ]; //NOTE: // mod_names[] is the global storage for the current mod names, // declared in CON_EXT.C // If mod_names[ 0 ] != NULL, a mod is currently active if ( mod_numnames >= MAX_REGISTERED_MODS ) { return FALSE; } mod_names[ mod_numnames ] = (char *) ALLOCMEM( strlen( name ) + 1 ); if ( mod_names[ mod_numnames ] == NULL ) { return FALSE; } strcpy( mod_names[ mod_numnames ], name ); // allocate memory for "name/name.dat" string char *packagename = (char *) ALLOCMEM( strlen( name ) * 2 + 6 ); if ( packagename == NULL ) { return FALSE; } strcpy( packagename, name ); strcat( packagename, "/" ); strcat( packagename, name ); strcat( packagename, ".dat" ); if ( !SYS_RegisterPackage( packagename, 0, name ) ) { MSGOUT( "CLI error: package registration failed (%s).\n", name ); MSGOUT( "CLI error: continuing without package.\n" ); } mod_numnames++; FREEMEM( packagename ); // set override flag mod_override = TRUE; return TRUE; }
// check vector length for zero ----------------------------------------------- // INLINE int LenZero( hprec_t len ) { ASSERT( len >= 0 ); if ( len < EPS_VECLEN ) { MSGOUT( "radar: diminishing vector encountered." ); return TRUE; } return FALSE; }
// load objects from binary data files ---------------------------------------- // PRIVATE void LoadObjectData() { // set global number of object classes NumObjClasses = NumLoadedObjects; // exit if nothing to read if ( NumLoadedObjects == 0 ) { MSGOUT( "*** WARNING: No objects at all. ***\n" ); return; } if ( display_info ) { MSGPUT( "Loading objects" ); if ( show_objects_loaded ) { MSGOUT( ":\n" ); } else { MSGPUT( "..." ); } } // load all object data for ( int oid = 0; oid < NumLoadedObjects; oid++ ) { if ( display_info ) { if ( show_objects_loaded ) { MSGOUT( "loading \"%s\" (object)\n", ObjectInfo[ oid ].file ); } else if ( ( oid & 0x01 ) == 0 ) { MSGPUT( "." ); } } // load object in odt format OBJ_LoadODT( oid, OBJLOAD_DEFAULT, NULL ); } if ( display_info ) { MSGOUT( "done.\n" ); } }
// store the CRC in an external packet ---------------------------------------- // PRIVATE void GMSV_NetPacketExternal_StoreCRC( NetPacketExternal_GMSV* ext_gamepacket, size_t pktsize ) { // challenge we got from server //FIXME: this should go into a module NET_GLOB_GMSV //extern int CS_connect_challenge; // set the crc32 field to known value and calculate the CRC for the header ext_gamepacket->crc32 = 0; ext_gamepacket->crc32 = NET_CalcCRC( (void*)ext_gamepacket, pktsize ); #ifdef SHOW_CRC32_WHEN_SENDING DBGTXT( MSGOUT( "CRC32 of packet %d is %x", ext_gamepacket->MessageId, ext_gamepacket->crc32 ); );
// execute received remote event: create object ------------------------------- // void NET_ExecRmEvCreateObject( RE_Header *rmev, int ownerid ) { ASSERT( rmev != NULL ); ASSERT( rmev->RE_Type == RE_CREATEOBJECT ); ASSERT( ( ownerid >= 0 ) && ( ownerid < MAX_NET_PROTO_PLAYERS ) ); RE_CreateObject *re_co = (RE_CreateObject *) rmev; GenObject *objpo = CreateObject( re_co->ObjectClass, re_co->ObjPosition ); ASSERT( objpo != NULL ); objpo->HostObjNumber = re_co->HostObjId; //TODO: // re_co->Flags RMEVTXT( MSGOUT( "--executing RE_CREATEOBJECT: %d (%d).", re_co->ObjectClass, ownerid ); );
// register default command line options and exec all registered options ------ // void SYSs_CheckCommandLine( int argc, char **argv ) { // set default name of local player strncpy( LocalPlayerName, default_player_name, MAX_PLAYER_NAME ); LocalPlayerName[ MAX_PLAYER_NAME ] = 0; // register default command line options RegisterDefaultOptions(); // exec all registered command line options if ( !OPT_ExecRegisteredOptions( argc, argv ) ) { MSGOUT( options_invalid ); exit( EXIT_SUCCESS ); } }
// commit demo cut by saving the cut area to file ----------------------------- // PRIVATE void CommitDemoCut() { ASSERT( demo_cutpos != NULL ); ASSERT( demo_data != NULL ); strcpy( paste_str, demo_cut_name ); strcat( paste_str, dem_extension ); FILE *fp = fopen( paste_str, "wb" ); if ( fp == NULL ) { MSGOUT( cut_open_error ); return; } // compile the state header if ( !CompileDemoCut( fp, demo_cut_name ) ) { MSGOUT( cut_write_error ); } // extract the cut area from the original demo ASSERT( demo_replaypos >= demo_cutpos ); size_t demsize = demo_replaypos - demo_cutpos; if ( fwrite( demo_cutpos, 1, demsize, fp ) != demsize ) { MSGOUT( cut_write_error ); fclose( fp ); return; } // write eof marker and close file int endmarker = 0; if ( fwrite( &endmarker, sizeof( endmarker ), 1, fp ) != 1 ) MSGOUT( cut_write_error ); fclose( fp ); }
// 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; }
// cache demo text as bitmap or textures -------------------------------------- // PRIVATE void InitDemoTextCache( int lineid ) { ASSERT(0); ASSERT( (dword)lineid < DEMOTEXT_NUM_LINES ); // size of buffer for string blit size_t bufsize = Screen_Width * Screen_BytesPerPixel * 80; //NOTE: // using Screen_Pitch instead of ( Screen_Width * Screen_BytesPerPixel ) // doesn't always work here because on a Voodoo3 Screen_Pitch will be set // to 2048, as on all other Voodoos. this is too low for resolutions // higher than 1024x768. demotext_fontmem[ lineid ] = (char *) ALLOCMEM( bufsize ); if ( demotext_fontmem[ lineid ] == NULL ) OUTOFMEM( 0 ); memset( demotext_fontmem[ lineid ], 0, bufsize ); int charsetid = demotext_charset_id[ lineid ]; D_SetWStrContext( CharsetInfo[ charsetid ].charsetpointer, CharsetInfo[ charsetid ].geompointer, demotext_fontmem[ lineid ], CharsetInfo[ charsetid ].width, CharsetInfo[ charsetid ].height ); if ( demotext_capitals[ lineid ] ) { strupr( demotext_text[ lineid ] ); } else { strlwr( demotext_text[ lineid ] ); } int swidth = D_GetPStringWidth( demotext_text[ lineid ] ); if ( swidth <= Screen_Width ) { // D_WritePString( demotext_text[ lineid ], (Screen_Width-swidth)/2, 0 ); } else { MSGOUT( "string too long." ); } // split up bitmap into appropriately sized textures if necessary if ( VidInfo_UseIterForDemoTexts ) { CreateBitmapTextures( &demotext_fontmem[ lineid ] ); } }
// retrieve received udp packet and store into listen buffer ------------------ // int UDP_FetchPacket( int bufid ) { // assume buffer is busy (nothing received) ListenStatus[ bufid ] = TRUE; int len = sizeof( sockaddr_in ); sockaddr_in from_adress; // receive packet on socket int rc = recvfrom( udp_socket, (char *) RecvNetPacketExternal, NET_UDP_DATA_LENGTH, 0, (SA *)&from_adress, (socklen_t *) &len ); if ( rc >= 0 ) { // copy from adress memcpy( &ListenAddress[ bufid ], &from_adress, sizeof( sockaddr_in ) ); // filter broadcast packets that are looping back if ( NETs_CompareNodes( &LocalNode, NETs_GetSender( bufid ) ) == NODECMP_EQUAL ) { DBGTXT( MSGOUT( "NET_UDP::UDP_FetchPacket(): dropped packet [loop-back]." ); );
// determine actually needed size of packet (strip unused remote event area) -- // PRIVATE size_t GMSV_NetPacketExternal_GetSize( NetPacketExternal_GMSV* ext_gamepacket_GMSV ) { //NOTE: // even though this function is operating on a packet in network byte-order, // swapping is not necessary since all accesses are byte-sized. (that is, // byte-ordering is entirely irrelevant.) // header is always needed size_t psize = sizeof( NetPacketExternal_GMSV ) - sizeof( dword ); // add size of remote event list psize += NET_RmEvList_GetSize( (RE_Header *) &ext_gamepacket_GMSV->RE_List ); //ASSERT( psize <= (size_t)NET_MAX_DATA_LENGTH ); if(psize >= (size_t)NET_MAX_DATA_LENGTH ) MSGOUT("CRAZYSPENCE: Packet size larger than %d: %d",NET_MAX_DATA_LENGTH,psize); return psize; }
// animate extra objects (only needed in entry mode/floating menu) ------------ // void OBJ_BackgroundAnimateExtras() { //NOTE: // this function is only used in entry mode and floating menu // to animate the extras when no other animations are performed. // in game mode these tasks are performed by // OBJ_COLL::CheckShipExtraCollision() to scan the extras list // only once. ASSERT( EntryMode || InFloatingMenu ); ASSERT( ExtraObjects != NULL ); ExtraObject *precnode = ExtraObjects; while ( precnode->NextObj != NULL ) { ASSERT( OBJECT_TYPE_EXTRA( precnode->NextObj ) ); // get pointer to current extra ExtraObject *curextra = (ExtraObject *) precnode->NextObj; ASSERT( curextra != NULL ); // check if lifetime of extra is spent curextra->LifeTimeCount -= CurScreenRefFrames; if ( curextra->LifeTimeCount < 0 ) { #ifdef INTERNAL_VERSION if ( NET_ConnectedGMSV() ) { //ASSERT( FALSE ); MSGOUT( "OBJ_ANI::OBJ_BackgroundAnimateExtras(): predicted freeing of extra object" ); } #endif // INTERNAL_VERSION OBJ_KillExtra( precnode, FALSE ); continue; } // animate this extra OBJ_AnimateExtra( curextra ); // advance to next extra in list precnode = curextra; } }
// draw the mouse cursor ------------------------------------------------------ // int DrawMouseCursor() { if ( ( !InFloatingMenu || AUX_DISABLE_FLOATING_MENU_DRAWING ) && !InStarMap ) return FALSE; if ( !AUX_ENABLE_MOUSE_FOR_MENU_SCREENS ) return FALSE; mousestate_s mousestate; int mouseavailable = INPs_MouseGetState( &mousestate ); // check if mouse is there and the custom cursor is enabled if ( !mouseavailable || !mousestate.drawcursor ) { return FALSE; } // acquire mouse cursor texture map once if already loaded static TextureMap *texmap = NULL; if ( texmap == NULL ) { texmap = FetchTextureMap( cursor_texname ); if ( texmap == NULL ) { MSGOUT( "texture '%s' was not found", cursor_texname ); return FALSE; } } texscreenrect_s rect; rect.itertype = iter_texrgba | iter_alphablend; rect.alpha = 255; rect.x = (int) ( mousestate.xpos * Screen_Width ); rect.y = (int) ( mousestate.ypos * Screen_Height ); rect.w = CURSOR_TEXWIDTH; rect.h = CURSOR_TEXHEIGHT; rect.scaled_w = CURSOR_SCREENWIDTH; rect.scaled_h = CURSOR_SCREENHEIGHT; rect.texofsx = 0; rect.texofsy = 0; rect.texmap = texmap; DRAW_TexturedScreenRect( &rect, NULL ); return TRUE; }
// set player name ------------------------------------------------------------ // PRIVATE int SLm_SetPlayerName( char **playername ) { char *name = playername[ 0 ]; int len = strlen( name ); if ( ( len < 2 ) || ( len > MAX_PLAYER_NAME ) ) { return FALSE; } strncpy( ForcedPlayerName, name, MAX_PLAYER_NAME ); ForcedPlayerName[ MAX_PLAYER_NAME ] = 0; if ( !SLm_CheckPlayerName( ForcedPlayerName ) ) { MSGOUT( "CLI error: player name contains invalid characters.\n" ); return FALSE; } return TRUE; }
// set a global aux flag to the specified value ------------------------------- // PRIVATE int SLm_SetAuxFlag( int *auxinfo ) { int auxflag = auxinfo[ 0 ]; int auxval = auxinfo[ 1 ]; // check flag id if ( ( auxflag < 0 ) || ( auxflag >= MAX_AUX_ENABLING ) ) { MSGOUT( "CLI error: auxflag out of range.\n" ); return FALSE; } //NOTE: // the value will not be checked against any bounds here. // as long as the flag id is valid, the value will be used as is. // set value for flag AuxEnabling[ auxflag ] = auxval; return TRUE; }