Update of /cvsroot/opentnl/tnl/zap
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3186/zap
Modified Files:
CTFGame.cpp game.cpp game.h gameConnection.cpp gameType.cpp
item.cpp moveObject.cpp projectile.cpp sfx.cpp sfx.h ship.cpp
teleporter.cpp
Log Message:
Assorted fixes and cleanups.
Team chat works now.
Fixed messed up linebreaks.
Redid sound engine.
Index: moveObject.cpp
===================================================================
RCS file: /cvsroot/opentnl/tnl/zap/moveObject.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** moveObject.cpp 20 Apr 2004 18:55:58 -0000 1.3
--- moveObject.cpp 20 Apr 2004 19:25:48 -0000 1.4
***************
*** 299,304 ****
{
// Make a noise...
! //SFXHandle h = new SFXObject(SFXBounceWall, collisionPoint, Point());
! //h->play();
Color bumpC(scale/3, scale/3, scale);
--- 299,303 ----
{
// Make a noise...
! SFXObject::play(SFXBounceWall, collisionPoint, Point());
Color bumpC(scale/3, scale/3, scale);
***************
*** 340,346 ****
shipHit->mMoveState[stateIndex].vel += collisionVector * (v2f - v2i);
! //SFXHandle h = new SFXObject(SFXBounceObject, shipHit->mMoveState[stateIndex].pos, Point());
! //h->play();
!
}
--- 339,343 ----
shipHit->mMoveState[stateIndex].vel += collisionVector * (v2f - v2i);
! SFXObject::play(SFXBounceObject, shipHit->mMoveState[stateIndex].pos, Point());
}
Index: gameType.cpp
===================================================================
RCS file: /cvsroot/opentnl/tnl/zap/gameType.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** gameType.cpp 20 Apr 2004 18:40:19 -0000 1.2
--- gameType.cpp 20 Apr 2004 19:25:48 -0000 1.3
***************
*** 1,278 ****
! //-----------------------------------------------------------------------------------
! //
! // Torque Network Library - ZAP example multiplayer vector graphics space game
! // Copyright (C) 2004 GarageGames.com, Inc.
! // For more information see http://www.opentnl.org
! //
! // 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.
! //
! // For use in products that are not compatible with the terms of the GNU
! // General Public License, alternative licensing options are available
! // from GarageGames.com.
! //
! // 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
! //
! //------------------------------------------------------------------------------------
!
! #include "gameType.h"
! #include "ship.h"
! #include "UIGame.h"
! #include "gameNetInterface.h"
!
! namespace Zap
! {
!
! TNL_IMPLEMENT_NETOBJECT(GameType);
!
! GameType::GameType()
! {
! mNetFlags.set(Ghostable);
! }
!
! void GameType::processArguments(S32 argc, const char **argv)
! {
!
! }
!
! void GameType::onAddedToGame(Game *theGame)
! {
! theGame->setGameType(this);
! setInterface(theGame->getNetInterface());
! if(!isGhost())
! setScopeAlways();
! }
!
! bool GameType::processLevelItem(S32 argc, const char **argv)
! {
! if(!stricmp(argv[0], "Team"))
! {
! if(argc < 5)
! return false;
! Team t;
! t.numPlayers = 0;
!
! t.name.set(argv[1]);
! t.color.read(argv + 2);
! mTeams.push_back(t);
! }
! else if(!stricmp(argv[0], "Spawn"))
! {
! if(argc < 4)
! return false;
! S32 teamIndex = atoi(argv[1]);
! Point p;
! p.read(argv + 2);
! p *= getGame()->getGridSize();
! if(teamIndex >= 0 && teamIndex < mTeams.size())
! mTeams[teamIndex].spawnPoints.push_back(p);
! }
! else
! return false;
! return true;
! }
!
! S32 GameType::findClientIndexByConnection(GameConnection *theConnection)
! {
! for(S32 clientIndex = 0; clientIndex < mClientList.size(); clientIndex++)
! if(mClientList[clientIndex].clientConnection == theConnection)
! return clientIndex;
! return -1;
! }
!
! S32 GameType::findClientIndexById(U32 clientId)
! {
! for(S32 clientIndex = 0; clientIndex < mClientList.size(); clientIndex++)
! if(mClientList[clientIndex].clientId == clientId)
! return clientIndex;
! return -1;
! }
!
! void GameType::spawnShip(GameConnection *theClient)
! {
! S32 clientIndex = findClientIndexByConnection(theClient);
! S32 teamIndex = mClientList[clientIndex].teamId;
!
! Point spawnPoint;
! S32 spawnIndex = Random::readI() % mTeams[teamIndex].spawnPoints.size();
! spawnPoint = mTeams[teamIndex].spawnPoints[spawnIndex];
!
! Ship *newShip = new Ship(spawnPoint, mTeams[teamIndex].color);
! newShip->addToGame(getGame());
! theClient->setControlObject(newShip);
! }
!
! void GameType::serverAddClient(GameConnection *theClient)
! {
! ClientRef cref;
! cref.clientId = theClient->mClientId;
! cref.name = theClient->playerName;
!
! cref.clientConnection = theClient;
! U32 minPlayers = mTeams[0].numPlayers;
! S32 minTeamIndex = 0;
! for(S32 i = 1; i < mTeams.size(); i++)
! {
! if(mTeams[i].numPlayers < minPlayers)
! {
! minTeamIndex = i;
! minPlayers = mTeams[i].numPlayers;
! }
! }
! cref.teamId = minTeamIndex;
! mClientList.push_back(cref);
!
! mTeams[cref.teamId].numPlayers++;
!
! s2cAddClient(cref.clientId, cref.name, false);
! s2cClientJoinedTeam(cref.clientId, cref.teamId);
! spawnShip(theClient);
! }
!
! void GameType::controlObjectForClientKilled(GameConnection *theClient)
! {
! spawnShip(theClient);
! }
!
! void GameType::addClientGameMenuOptions(Vector<const char *> &menuOptions)
! {
! if(mTeams.size() > 1)
! menuOptions.push_back("CHANGE TEAMS");
! }
!
! void GameType::processClientGameMenuOption(U32 index)
! {
! if(index == 0)
! c2sChangeTeams();
! }
!
! TNL_IMPLEMENT_NETOBJECT_RPC(GameType, s2cAddClient, (U32 id, StringTableEntry name, bool isMyClient),
! NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhost, 0)
! {
! ClientRef cref;
! cref.clientId = id;
! cref.name = name;
! cref.teamId = 0;
! mClientList.push_back(cref);
!
! if(isMyClient)
! mThisClientId = id;
! gGameUserInterface.displayMessage(Color(0.6f, 0.6f, 0.8f), "%s joined the game.", name.getString());
! }
!
! void GameType::serverRemoveClient(GameConnection *theClient)
! {
! S32 clientIndex = findClientIndexByConnection(theClient);
! mTeams[mClientList[clientIndex].teamId].numPlayers--;
! mClientList.erase(clientIndex);
!
! GameObject *theControlObject = theClient->getControlObject();
! if(theControlObject)
! delete theControlObject;
!
! s2cRemoveClient(theClient->mClientId);
! }
!
! TNL_IMPLEMENT_NETOBJECT_RPC(GameType, s2cRemoveClient, (U32 id),
! NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhost, 0)
! {
! S32 clientIndex = findClientIndexById(id);
! mClientList.erase(clientIndex);
! }
!
! TNL_IMPLEMENT_NETOBJECT_RPC(GameType, s2cAddTeam, (StringTableEntry teamName, F32 r, F32 g, F32 b),
! NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhost, 0)
! {
! Team team;
! team.name = teamName;
! team.color.r = r;
! team.color.g = g;
! team.color.b = b;
! mTeams.push_back(team);
! }
!
! TNL_IMPLEMENT_NETOBJECT_RPC(GameType, s2cSetTeamScore, (U32 teamIndex, U32 score),
! NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhost, 0)
! {
! mTeams[teamIndex].score = score;
! }
!
! TNL_IMPLEMENT_NETOBJECT_RPC(GameType, s2cClientJoinedTeam, (U32 clientId, U32 teamIndex),
! NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhost, 0)
! {
! S32 clientIndex = findClientIndexById(clientId);
! mClientList[clientIndex].teamId = teamIndex;
! gGameUserInterface.displayMessage(Color(0.6f, 0.6f, 0.8f), "%s joined team %s.", mClientList[clientIndex].name.getString(), mTeams[teamIndex].name.getString());
! }
!
! TNL_IMPLEMENT_NETOBJECT_RPC(GameType, c2sChangeTeams, (),
! NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhostParent, 0)
! {
! if(mTeams.size() <= 1)
! return;
!
! GameConnection *source = (GameConnection *) NetObject::getRPCSourceConnection();
! S32 clientIndex = findClientIndexByConnection(source);
!
! // destroy the old ship
! GameObject *co = source->getControlObject();
! if(co)
! getGame()->deleteObject(co, 0);
!
! U32 newTeamId = (mClientList[clientIndex].teamId + 1) % mTeams.size();
! mClientList[clientIndex].teamId = newTeamId;
! s2cClientJoinedTeam(mClientList[clientIndex].clientId, newTeamId);
! spawnShip(source);
! }
!
! void GameType::onGhostAvailable(GhostConnection *theConnection)
! {
! NetObject::setRPCDestConnection(theConnection);
!
! for(S32 i = 0; i < mTeams.size(); i++)
! {
! s2cAddTeam(mTeams[i].name, mTeams[i].color.r, mTeams[i].color.g, mTeams[i].color.b);
! s2cSetTeamScore(i, mTeams[i].score);
! }
!
! // add all the client and team information
! for(S32 i = 0; i < mClientList.size(); i++)
! {
! s2cAddClient(mClientList[i].clientId, mClientList[i].name, mClientList[i].clientConnection == theConnection);
! s2cClientJoinedTeam(mClientList[i].clientId, mClientList[i].teamId);
! }
! NetObject::setRPCDestConnection(NULL);
! }
!
! TNL_IMPLEMENT_NETOBJECT_RPC(GameType, c2sSendChat, (bool global, const char *message),
! NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhostParent, 0)
! {
! GameConnection *source = (GameConnection *) getRPCSourceConnection();
!
! RefPtr<NetEvent> theEvent = TNL_RPC_CONSTRUCT_NETEVENT(this,
! s2cDisplayChatMessage, (global, source->playerName, message));
! for(S32 i = 0; i < mClientList.size(); i++)
! mClientList[i].clientConnection->postNetEvent(theEvent);
! }
!
! extern Color gGlobalChatColor;
! extern Color gTeamChatColor;
!
! TNL_IMPLEMENT_NETOBJECT_RPC(GameType, s2cDisplayChatMessage, (bool global, StringTableEntry clientName, const char *message),
! NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhost, 0)
! {
! Color theColor = global ? gGlobalChatColor : gTeamChatColor;
!
! gGameUserInterface.displayMessage(theColor, "%s: %s", clientName.getString(), message);
! }
!
};
\ No newline at end of file
--- 1,289 ----
! //-----------------------------------------------------------------------------------
! //
! // Torque Network Library - ZAP example multiplayer vector graphics space game
! // Copyright (C) 2004 GarageGames.com, Inc.
! // For more information see http://www.opentnl.org
! //
! // 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.
! //
! // For use in products that are not compatible with the terms of the GNU
! // General Public License, alternative licensing options are available
! // from GarageGames.com.
! //
! // 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
! //
! //------------------------------------------------------------------------------------
!
! #include "gameType.h"
! #include "ship.h"
! #include "UIGame.h"
! #include "gameNetInterface.h"
!
! namespace Zap
! {
!
! TNL_IMPLEMENT_NETOBJECT(GameType);
!
! GameType::GameType()
! {
! mNetFlags.set(Ghostable);
! }
!
! void GameType::processArguments(S32 argc, const char **argv)
! {
!
! }
!
! void GameType::onAddedToGame(Game *theGame)
! {
! theGame->setGameType(this);
! setInterface(theGame->getNetInterface());
! if(!isGhost())
! setScopeAlways();
! }
!
! bool GameType::processLevelItem(S32 argc, const char **argv)
! {
! if(!stricmp(argv[0], "Team"))
! {
! if(argc < 5)
! return false;
! Team t;
! t.numPlayers = 0;
!
! t.name.set(argv[1]);
! t.color.read(argv + 2);
! mTeams.push_back(t);
! }
! else if(!stricmp(argv[0], "Spawn"))
! {
! if(argc < 4)
! return false;
! S32 teamIndex = atoi(argv[1]);
! Point p;
! p.read(argv + 2);
! p *= getGame()->getGridSize();
! if(teamIndex >= 0 && teamIndex < mTeams.size())
! mTeams[teamIndex].spawnPoints.push_back(p);
! }
! else
! return false;
! return true;
! }
!
! S32 GameType::findClientIndexByConnection(GameConnection *theConnection)
! {
! for(S32 clientIndex = 0; clientIndex < mClientList.size(); clientIndex++)
! if(mClientList[clientIndex].clientConnection == theConnection)
! return clientIndex;
! return -1;
! }
!
! S32 GameType::findClientIndexById(U32 clientId)
! {
! for(S32 clientIndex = 0; clientIndex < mClientList.size(); clientIndex++)
! if(mClientList[clientIndex].clientId == clientId)
! return clientIndex;
! return -1;
! }
!
! void GameType::spawnShip(GameConnection *theClient)
! {
! S32 clientIndex = findClientIndexByConnection(theClient);
! S32 teamIndex = mClientList[clientIndex].teamId;
!
! Point spawnPoint;
! S32 spawnIndex = Random::readI() % mTeams[teamIndex].spawnPoints.size();
! spawnPoint = mTeams[teamIndex].spawnPoints[spawnIndex];
!
! Ship *newShip = new Ship(spawnPoint, mTeams[teamIndex].color);
! newShip->addToGame(getGame());
! theClient->setControlObject(newShip);
! }
!
! void GameType::serverAddClient(GameConnection *theClient)
! {
! ClientRef cref;
! cref.clientId = theClient->mClientId;
! cref.name = theClient->playerName;
!
! cref.clientConnection = theClient;
! U32 minPlayers = mTeams[0].numPlayers;
! S32 minTeamIndex = 0;
! for(S32 i = 1; i < mTeams.size(); i++)
! {
! if(mTeams[i].numPlayers < minPlayers)
! {
! minTeamIndex = i;
! minPlayers = mTeams[i].numPlayers;
! }
! }
! cref.teamId = minTeamIndex;
! mClientList.push_back(cref);
!
! mTeams[cref.teamId].numPlayers++;
!
! s2cAddClient(cref.clientId, cref.name, false);
! s2cClientJoinedTeam(cref.clientId, cref.teamId);
! spawnShip(theClient);
! }
!
! void GameType::controlObjectForClientKilled(GameConnection *theClient)
! {
! spawnShip(theClient);
! }
!
! void GameType::addClientGameMenuOptions(Vector<const char *> &menuOptions)
! {
! if(mTeams.size() > 1)
! menuOptions.push_back("CHANGE TEAMS");
! }
!
! void GameType::processClientGameMenuOption(U32 index)
! {
! if(index == 0)
! c2sChangeTeams();
! }
!
! TNL_IMPLEMENT_NETOBJECT_RPC(GameType, s2cAddClient, (U32 id, StringTableEntry name, bool isMyClient),
! NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhost, 0)
! {
! ClientRef cref;
! cref.clientId = id;
! cref.name = name;
! cref.teamId = 0;
! mClientList.push_back(cref);
!
! if(isMyClient)
! mThisClientId = id;
! gGameUserInterface.displayMessage(Color(0.6f, 0.6f, 0.8f), "%s joined the game.", name.getString());
! }
!
! void GameType::serverRemoveClient(GameConnection *theClient)
! {
! S32 clientIndex = findClientIndexByConnection(theClient);
! mTeams[mClientList[clientIndex].teamId].numPlayers--;
! mClientList.erase(clientIndex);
!
! GameObject *theControlObject = theClient->getControlObject();
! if(theControlObject)
! delete theControlObject;
!
! s2cRemoveClient(theClient->mClientId);
! }
!
! TNL_IMPLEMENT_NETOBJECT_RPC(GameType, s2cRemoveClient, (U32 id),
! NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhost, 0)
! {
! S32 clientIndex = findClientIndexById(id);
! mClientList.erase(clientIndex);
! }
!
! TNL_IMPLEMENT_NETOBJECT_RPC(GameType, s2cAddTeam, (StringTableEntry teamName, F32 r, F32 g, F32 b),
! NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhost, 0)
! {
! Team team;
! team.name = teamName;
! team.color.r = r;
! team.color.g = g;
! team.color.b = b;
! mTeams.push_back(team);
! }
!
! TNL_IMPLEMENT_NETOBJECT_RPC(GameType, s2cSetTeamScore, (U32 teamIndex, U32 score),
! NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhost, 0)
! {
! mTeams[teamIndex].score = score;
! }
!
! TNL_IMPLEMENT_NETOBJECT_RPC(GameType, s2cClientJoinedTeam, (U32 clientId, U32 teamIndex),
! NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhost, 0)
! {
! S32 clientIndex = findClientIndexById(clientId);
! mClientList[clientIndex].teamId = teamIndex;
! gGameUserInterface.displayMessage(Color(0.6f, 0.6f, 0.8f), "%s joined team %s.", mClientList[clientIndex].name.getString(), mTeams[teamIndex].name.getString());
! }
!
! TNL_IMPLEMENT_NETOBJECT_RPC(GameType, c2sChangeTeams, (),
! NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhostParent, 0)
! {
! if(mTeams.size() <= 1)
! return;
!
! GameConnection *source = (GameConnection *) NetObject::getRPCSourceConnection();
! S32 clientIndex = findClientIndexByConnection(source);
!
! // destroy the old ship
! GameObject *co = source->getControlObject();
! if(co)
! getGame()->deleteObject(co, 0);
!
! U32 newTeamId = (mClientList[clientIndex].teamId + 1) % mTeams.size();
! mClientList[clientIndex].teamId = newTeamId;
! s2cClientJoinedTeam(mClientList[clientIndex].clientId, newTeamId);
! spawnShip(source);
! }
!
! void GameType::onGhostAvailable(GhostConnection *theConnection)
! {
! NetObject::setRPCDestConnection(theConnection);
!
! for(S32 i = 0; i < mTeams.size(); i++)
! {
! s2cAddTeam(mTeams[i].name, mTeams[i].color.r, mTeams[i].color.g, mTeams[i].color.b);
! s2cSetTeamScore(i, mTeams[i].score);
! }
!
! // add all the client and team information
! for(S32 i = 0; i < mClientList.size(); i++)
! {
! s2cAddClient(mClientList[i].clientId, mClientList[i].name, mClientList[i].clientConnection == theConnection);
! s2cClientJoinedTeam(mClientList[i].clientId, mClientList[i].teamId);
! }
! NetObject::setRPCDestConnection(NULL);
! }
!
! TNL_IMPLEMENT_NETOBJECT_RPC(GameType, c2sSendChat, (bool global, const char *message),
! NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhostParent, 0)
! {
! GameConnection *source = (GameConnection *) getRPCSourceConnection();
!
! RefPtr<NetEvent> theEvent = TNL_RPC_CONSTRUCT_NETEVENT(this,
! s2cDisplayChatMessage, (global, source->playerName, message));
!
! S32 teamId = 0;
!
! if(!global)
! for(S32 i = 0; i < mClientList.size(); i++)
! if(mClientList[i].clientId == source->mClientId)
! teamId = mClientList[i].teamId;
!
! for(S32 i = 0; i < mClientList.size(); i++)
! {
! if(global || mClientList[i].teamId == teamId)
! mClientList[i].clientConnection->postNetEvent(theEvent);
! }
! }
!
! extern Color gGlobalChatColor;
! extern Color gTeamChatColor;
!
! TNL_IMPLEMENT_NETOBJECT_RPC(GameType, s2cDisplayChatMessage, (bool global, StringTableEntry clientName, const char *message),
! NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhost, 0)
! {
! Color theColor = global ? gGlobalChatColor : gTeamChatColor;
!
! gGameUserInterface.displayMessage(theColor, "%s: %s", clientName.getString(), message);
! }
!
};
\ No newline at end of file
Index: projectile.cpp
===================================================================
RCS file: /cvsroot/opentnl/tnl/zap/projectile.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** projectile.cpp 20 Apr 2004 18:40:19 -0000 1.2
--- projectile.cpp 20 Apr 2004 19:25:48 -0000 1.3
***************
*** 1,223 ****
! //-----------------------------------------------------------------------------------
! //
! // Torque Network Library - ZAP example multiplayer vector graphics space game
! // Copyright (C) 2004 GarageGames.com, Inc.
! // For more information see http://www.opentnl.org
! //
! // 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.
! //
! // For use in products that are not compatible with the terms of the GNU
! // General Public License, alternative licensing options are available
! // from GarageGames.com.
! //
! // 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
! //
! //------------------------------------------------------------------------------------
!
! #include "projectile.h"
! #include "ship.h"
! #include "sparkManager.h"
! #include "sfx.h"
!
! #include "glutInclude.h"
!
! namespace Zap
! {
!
! TNL_IMPLEMENT_NETOBJECT(Projectile);
!
!
! Projectile::Projectile(Point p, Point v, U32 t, Ship *shooter)
! {
! mNetFlags.set(Ghostable);
! pos = p;
! velocity = v;
! liveTime = t;
! collided = false;
! mShooter = shooter;
! }
!
! U32 Projectile::packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream)
! {
! stream->write(pos.x);
! stream->write(pos.y);
! stream->write(velocity.x);
! stream->write(velocity.y);
! S32 index = -1;
! if(mShooter.isValid())
! index = connection->getGhostIndex(mShooter);
! if(stream->writeFlag(index != -1))
! stream->writeInt(index, GhostConnection::GhostIdBitSize);
!
! return 0;
! }
!
! void Projectile::unpackUpdate(GhostConnection *connection, BitStream *stream)
! {
! stream->read(&pos.x);
! stream->read(&pos.y);
! stream->read(&velocity.x);
! stream->read(&velocity.y);
!
! if(stream->readFlag())
! mShooter = (Ship *) connection->resolveGhost(stream->readInt(GhostConnection::GhostIdBitSize));
!
! Rect newExtent(pos,pos);
! setExtent(newExtent);
! process(connection->getOneWayTime());
!
! SFXObject::play(0, pos, velocity);
! }
!
! enum {
! NumSparkColors = 4,
! };
!
! Color SparkColors[NumSparkColors] = {
! Color(1, 0, 1),
! Color(1, 1, 1),
! Color(0, 0, 1),
! Color(1, 0, 0),
! };
! void Projectile::handleCollision(GameObject *hitObject, Point collisionPoint)
! {
! collided = true;
!
! if(!isGhost())
! {
! DamageInfo theInfo;
! theInfo.collisionPoint = collisionPoint;
! theInfo.damageAmount = 1;
! theInfo.damageType = 0;
! theInfo.damagingObject = this;
! theInfo.impulseVector = velocity;
!
! hitObject->damageObject(&theInfo);
! }
! liveTime = 0;
!
! // Do some particle spew...
! if(isGhost())
! {
! SparkManager::emitExplosion(collisionPoint, 0.4, SparkColors, NumSparkColors);
! SFXObject::play(SFXPhaserImpact, pos, velocity);
! }
! }
!
! void Projectile::process(U32 deltaT)
! {
! if(collided)
! return;
!
! Point endPos = pos + velocity * deltaT * 0.001;
! static Vector<GameObject *> disableVector;
!
! Rect queryRect(pos, endPos);
!
! float collisionTime;
! disableVector.clear();
!
! if(mShooter.isValid())
! {
! disableVector.push_back(mShooter);
! mShooter->disableCollision();
! }
!
! GameObject *hitObject;
! for(;;)
! {
! hitObject = findObjectLOS(MoveableType | BarrierType, MoveObject::RenderState, pos, endPos, collisionTime);
! if(!hitObject || hitObject->collide(this))
! break;
! disableVector.push_back(hitObject);
! hitObject->disableCollision();
! }
!
! for(S32 i = 0; i < disableVector.size(); i++)
! disableVector[i]->enableCollision();
!
! if(hitObject)
! {
! Point collisionPoint = pos + (endPos - pos) * collisionTime;
! handleCollision(hitObject, collisionPoint);
! }
! else
! pos = endPos;
!
! Rect newExtent(pos,pos);
! setExtent(newExtent);
! }
!
! void Projectile::processServer(U32 deltaT)
! {
! process(deltaT);
! if(liveTime)
! {
! if(liveTime <= deltaT)
! {
! getGame()->deleteObject(this, 500);
! liveTime = 0;
! }
! else
! liveTime -= deltaT;
! }
! }
!
! void Projectile::processClient(U32 deltaT)
! {
! process(deltaT);
! liveTime += deltaT;
! }
!
! void Projectile::render()
! {
! if(collided)
! return;
!
! glColor3f(1,0,0.5);
! glPushMatrix();
! glTranslatef(pos.x, pos.y, 0);
!
! glPushMatrix();
! glRotatef((liveTime % 720) * 0.5, 0, 0, 1);
!
! glBegin(GL_LINE_LOOP);
! glVertex2f(-2, 2);
! glVertex2f(0, 6);
! glVertex2f(2, 2);
! glVertex2f(6, 0);
! glVertex2f(2, -2);
! glVertex2f(0, -6);
! glVertex2f(-2, -2);
! glVertex2f(-6, 0);
! glEnd();
!
! glPopMatrix();
!
! glRotatef(180 - (liveTime % 360), 0, 0, 1);
! glColor3f(0.5,0,1);
! glBegin(GL_LINE_LOOP);
! glVertex2f(-2, 2);
! glVertex2f(0, 8);
! glVertex2f(2, 2);
! glVertex2f(8, 0);
! glVertex2f(2, -2);
! glVertex2f(0, -8);
! glVertex2f(-2, -2);
! glVertex2f(-8, 0);
! glEnd();
!
! glPopMatrix();
! }
!
};
\ No newline at end of file
--- 1,223 ----
! //-----------------------------------------------------------------------------------
! //
! // Torque Network Library - ZAP example multiplayer vector graphics space game
! // Copyright (C) 2004 GarageGames.com, Inc.
! // For more information see http://www.opentnl.org
! //
! // 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.
! //
! // For use in products that are not compatible with the terms of the GNU
! // General Public License, alternative licensing options are available
! // from GarageGames.com.
! //
! // 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
! //
! //------------------------------------------------------------------------------------
!
! #include "projectile.h"
! #include "ship.h"
! #include "sparkManager.h"
! #include "sfx.h"
!
! #include "glutInclude.h"
!
! namespace Zap
! {
!
! TNL_IMPLEMENT_NETOBJECT(Projectile);
!
!
! Projectile::Projectile(Point p, Point v, U32 t, Ship *shooter)
! {
! mNetFlags.set(Ghostable);
! pos = p;
! velocity = v;
! liveTime = t;
! collided = false;
! mShooter = shooter;
! }
!
! U32 Projectile::packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream)
! {
! stream->write(pos.x);
! stream->write(pos.y);
! stream->write(velocity.x);
! stream->write(velocity.y);
! S32 index = -1;
! if(mShooter.isValid())
! index = connection->getGhostIndex(mShooter);
! if(stream->writeFlag(index != -1))
! stream->writeInt(index, GhostConnection::GhostIdBitSize);
!
! return 0;
! }
!
! void Projectile::unpackUpdate(GhostConnection *connection, BitStream *stream)
! {
! stream->read(&pos.x);
! stream->read(&pos.y);
! stream->read(&velocity.x);
! stream->read(&velocity.y);
!
! if(stream->readFlag())
! mShooter = (Ship *) connection->resolveGhost(stream->readInt(GhostConnection::GhostIdBitSize));
!
! Rect newExtent(pos,pos);
! setExtent(newExtent);
! process(connection->getOneWayTime());
!
! SFXObject::play(0, pos, velocity);
! }
!
! enum {
! NumSparkColors = 4,
! };
!
! Color SparkColors[NumSparkColors] = {
! Color(1, 0, 1),
! Color(1, 1, 1),
! Color(0, 0, 1),
! Color(1, 0, 0),
! };
! void Projectile::handleCollision(GameObject *hitObject, Point collisionPoint)
! {
! collided = true;
!
! if(!isGhost())
! {
! DamageInfo theInfo;
! theInfo.collisionPoint = collisionPoint;
! theInfo.damageAmount = 1;
! theInfo.damageType = 0;
! theInfo.damagingObject = this;
! theInfo.impulseVector = velocity;
!
! hitObject->damageObject(&theInfo);
! }
! liveTime = 0;
!
! // Do some particle spew...
! if(isGhost())
! {
! SparkManager::emitExplosion(collisionPoint, 0.4, SparkColors, NumSparkColors);
! SFXObject::play(SFXPhaserImpact, pos, velocity);
! }
! }
!
! void Projectile::process(U32 deltaT)
! {
! if(collided)
! return;
!
! Point endPos = pos + velocity * deltaT * 0.001;
! static Vector<GameObject *> disableVector;
!
! Rect queryRect(pos, endPos);
!
! float collisionTime;
! disableVector.clear();
!
! if(mShooter.isValid())
! {
! disableVector.push_back(mShooter);
! mShooter->disableCollision();
! }
!
! GameObject *hitObject;
! for(;;)
! {
! hitObject = findObjectLOS(MoveableType | BarrierType, MoveObject::RenderState, pos, endPos, collisionTime);
! if(!hitObject || hitObject->collide(this))
! break;
! disableVector.push_back(hitObject);
! hitObject->disableCollision();
! }
!
! for(S32 i = 0; i < disableVector.size(); i++)
! disableVector[i]->enableCollision();
!
! if(hitObject)
! {
! Point collisionPoint = pos + (endPos - pos) * collisionTime;
! handleCollision(hitObject, collisionPoint);
! }
! else
! pos = endPos;
!
! Rect newExtent(pos,pos);
! setExtent(newExtent);
! }
!
! void Projectile::processServer(U32 deltaT)
! {
! process(deltaT);
! if(liveTime)
! {
! if(liveTime <= deltaT)
! {
! getGame()->deleteObject(this, 500);
! liveTime = 0;
! }
! else
! liveTime -= deltaT;
! }
! }
!
! void Projectile::processClient(U32 deltaT)
! {
! process(deltaT);
! liveTime += deltaT;
! }
!
! void Projectile::render()
! {
! if(collided)
! return;
!
! glColor3f(1,0,0.5);
! glPushMatrix();
! glTranslatef(pos.x, pos.y, 0);
!
! glPushMatrix();
! glRotatef((liveTime % 720) * 0.5, 0, 0, 1);
!
! glBegin(GL_LINE_LOOP);
! glVertex2f(-2, 2);
! glVertex2f(0, 6);
! glVertex2f(2, 2);
! glVertex2f(6, 0);
! glVertex2f(2, -2);
! glVertex2f(0, -6);
! glVertex2f(-2, -2);
! glVertex2f(-6, 0);
! glEnd();
!
! glPopMatrix();
!
! glRotatef(180 - (liveTime % 360), 0, 0, 1);
! glColor3f(0.5,0,1);
! glBegin(GL_LINE_LOOP);
! glVertex2f(-2, 2);
! glVertex2f(0, 8);
! glVertex2f(2, 2);
! glVertex2f(8, 0);
! glVertex2f(2, -2);
! glVertex2f(0, -8);
! glVertex2f(-2, -2);
! glVertex2f(-8, 0);
! glEnd();
!
! glPopMatrix();
! }
!
};
\ No newline at end of file
Index: sfx.cpp
===================================================================
RCS file: /cvsroot/opentnl/tnl/zap/sfx.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** sfx.cpp 20 Apr 2004 18:40:19 -0000 1.4
--- sfx.cpp 20 Apr 2004 19:25:49 -0000 1.5
***************
*** 1,454 ****
! //-----------------------------------------------------------------------------------
! //
! // Torque Network Library - ZAP example multiplayer vector graphics space game
! // Copyright (C) 2004 GarageGames.com, Inc.
! // For more information see http://www.opentnl.org
! //
! // 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.
! //
! // For use in products that are not compatible with the terms of the GNU
! // General Public License, alternative licensing options are available
! // from GarageGames.com.
! //
! // 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
! //
! //------------------------------------------------------------------------------------
!
! #include "sfx.h"
! #include "tnl.h"
! #include "tnlLog.h"
!
! #if defined (TNL_OS_WIN32)
!
! #include "alInclude.h"
!
! using namespace TNL;
!
! namespace Zap
! {
!
! static SFXProfile gSFXProfiles[] = {
! { "phaser.wav", false, 0.45f, false, 150, 600 },
! { "phaser_impact.wav", false, 0.7f, false, 150, 600 },
! { "ship_explode.wav", false, 1.0, false, 300, 1000 },
! { "flag_capture.wav", true, 0.45f, false, 0, 0 },
! { "flag_drop.wav", true, 0.45f, false, 0, 0 },
! { "flag_return.wav", true, 0.45f, false, 0, 0 },
! { "flag_snatch.wav", true, 0.45f, false, 0, 0 },
! { "teleport_in.wav", false, 1.0, false, 200, 500 },
! { "teleport_out.wav", false, 1.0, false, 200, 500 },
! { NULL, false, 0, false, 0, 0 },
! };
!
! static ALCdevice *gDevice = NULL;
! static ALCcontext *gContext = NULL;
! static bool gSFXValid = false;
!
! enum {
! NumSources = 16,
! };
!
! static ALuint gSources[NumSources];
! static bool gSourceActive[NumSources];
! Point SFXObject::mListenerPosition;
! Point SFXObject::mListenerVelocity;
! F32 SFXObject::mMaxDistance = 500;
!
! static ALuint gBuffers[NumSFXBuffers];
! static Vector<SFXHandle> gPlayList;
!
! SFXObject::SFXObject(U32 profileIndex, F32 gain, Point position, Point velocity)
! {
! mSFXIndex = profileIndex;
! mProfile = gSFXProfiles + profileIndex;
! mGain = gain;
! mPosition = position;
! mVelocity = velocity;
! mSourceIndex = -1;
! mPriority = 0;
! }
!
! RefPtr<SFXObject> SFXObject::play(U32 profileIndex, F32 gain)
! {
! RefPtr<SFXObject> ret = new SFXObject(profileIndex, gain, Point(), Point());
! ret->play();
! return ret;
! }
!
! RefPtr<SFXObject> SFXObject::play(U32 profileIndex, Point position, Point velocity, F32 gain)
! {
! RefPtr<SFXObject> ret = new SFXObject(profileIndex, gain, position, velocity);
! ret->play();
! return ret;
! }
!
! SFXObject::~SFXObject()
! {
!
! }
!
! void SFXObject::updateGain()
! {
! ALuint source = gSources[mSourceIndex];
! F32 gain = mGain;
!
! if(!mProfile->isRelative)
! {
! F32 distance = (mListenerPosition - mPosition).len();
! if(distance > mProfile->fullGainDistance)
! {
! if(distance < mProfile->zeroGainDistance)
! gain *= (mProfile->fullGainDistance - distance) /
! (mProfile->zeroGainDistance - mProfile->fullGainDistance);
! else
! gain = 0.0f;
! }
! else
! gain = 1.0f;
! }
! else
! gain = 1.0f;
!
! alSourcef(source, AL_GAIN, gain * mProfile->gainScale);
! }
!
! void SFXObject::updateMovementParams()
! {
! ALuint source = gSources[mSourceIndex];
! if(mProfile->isRelative)
! {
! alSourcei(source, AL_SOURCE_RELATIVE, true);
! alSource3f(source, AL_POSITION, 0, 0, 0);
! //alSource3f(source, AL_VELOCITY, 0, 0, 0);
! }
! else
! {
! alSourcei(source, AL_SOURCE_RELATIVE, false);
! alSource3f(source, AL_POSITION, mPosition.x, mPosition.y, 0);
! //alSource3f(source, AL_VELOCITY, mVelocity.x, mVelocity.y, 0);
! }
! }
!
! void SFXObject::playOnSource()
! {
! ALuint source = gSources[mSourceIndex];
! alSourceStop(source);
! alSourcei(source, AL_BUFFER, gBuffers[mSFXIndex]);
! alSourcei(source, AL_LOOPING, mProfile->isLooping);
! updateMovementParams();
!
! updateGain();
! alSourcePlay(source);
! }
!
! void SFXObject::setGain(F32 gain)
! {
! mGain = gain;
! if(mSourceIndex != -1)
! updateGain();
! }
!
! void SFXObject::setMovementParams(Point position, Point velocity)
! {
! mPosition = position;
! mVelocity = velocity;
! if(mSourceIndex != -1)
! updateMovementParams();
! }
!
! void SFXObject::play()
! {
! if(mSourceIndex != -1)
! return;
! else
! {
! // see if it's on the play list:
! S32 i;
! for(i = 0; i < gPlayList.size(); i++)
! if(gPlayList[i] == this)
! return;
! gPlayList.push_back(this);
! }
! }
!
! void SFXObject::stop()
! {
! // remove from the play list, if this sound is playing:
! if(mSourceIndex != -1)
! {
! alSourceStop(gSources[mSourceIndex]);
! mSourceIndex = -1;
! }
! for(S32 i = 0; i < gPlayList.size(); i++)
! {
! if(gPlayList[i] == this)
! {
! gPlayList.erase(i);
! return;
! }
! }
! }
!
! void SFXObject::init()
! {
! gDevice = alcOpenDevice((ALubyte *) "DirectSound3D");
! if(!gDevice)
! {
! logprintf("Failed to intitialize OpenAL.");
! return;
! }
!
! static int contextData[][2] =
! {
! {ALC_FREQUENCY, 11025},
! {0,0} // Indicate end of list...
! };
!
! gContext = alcCreateContext(gDevice, (ALCint*)contextData);
! alcMakeContextCurrent(gContext);
!
! alGetError();
!
! alDistanceModel(AL_NONE);
!
! // load up all the sound buffers
! alGenBuffers(NumSFXBuffers, gBuffers);
!
! if(alGetError() != AL_NO_ERROR)
! return;
!
! alGenSources(NumSources, gSources);
!
! for(U32 i = 0; i < NumSFXBuffers; i++)
! {
! if(!gSFXProfiles[i].fileName)
! break;
!
! ALsizei size,freq;
! ALenum format;
! ALvoid *data;
! ALboolean loop;
!
! alutLoadWAVFile((ALbyte *) gSFXProfiles[i].fileName, &format, &data, &size, &freq, &loop);
! if(alGetError() != AL_NO_ERROR)
! return;
! alBufferData(gBuffers[i], format, data, size, freq);
! alutUnloadWAV(format, data, size, freq);
! if(alGetError() != AL_NO_ERROR)
! return;
! }
! gSFXValid = true;
! }
!
! void SFXObject::process()
! {
! if(!gSFXValid)
! return;
!
! // ok, so we have a list of currently "playing" sounds, which is
! // unbounded in length, but only the top NumSources actually have sources
! // associtated with them. Sounds are prioritized on a 0-1 scale
! // based on type and distance.
! // Each time through the main loop, newly played sounds are placed
! // on the process list. When SFXProcess is called, any finished sounds
! // are retired from the list, and then it prioritizes and sorts all
! // the remaining sounds. For any sounds from 0 to NumSources that don't
! // have a current source, they grab one of the sources not used by the other
! // top sounds. At this point, any sound that is not looping, and is
! // not in the active top list is retired.
!
! // ok, look through all the currently playing sources and see which
! // ones need to be retired:
!
! for(S32 i = 0; i < NumSources; i++)
! {
! ALint state;
! alGetSourcei(gSources[i], AL_SOURCE_STATE, &state);
! gSourceActive[i] = state != AL_STOPPED && state != AL_INITIAL;
! }
! for(S32 i = 0; i < gPlayList.size(); )
! {
! SFXHandle &s = gPlayList[i];
! if(s->mSourceIndex != -1 && !gSourceActive[s->mSourceIndex])
! {
! // this sound was playing; now it is stopped,
! // so remove it from the list.
! s->mSourceIndex = -1;
! gPlayList.erase_fast(i);
! }
! else
! {
! // compute a priority for this sound.
! if(!s->mProfile->isRelative)
! s->mPriority = (500 - (s->mPosition - mListenerPosition).len()) / 500.0f;
! else
! s->mPriority = 1.0;
! i++;
! }
! }
! // now, bubble sort all the sounds up the list:
! // we choose bubble sort, because the list should
! // have a lot of frame-to-frame coherency, making the
! // sort most often O(n)
! for(S32 i = 1; i < gPlayList.size(); i++)
! {
! F32 priority = gPlayList[i]->mPriority;
! for(S32 j = i - 1; j >= 0; j--)
! {
! if(priority > gPlayList[j]->mPriority)
! {
! SFXHandle temp = gPlayList[j];
! gPlayList[j] = gPlayList[j+1];
! gPlayList[j+1] = temp;
! }
! }
! }
! // last, release any sources and get rid of non-looping sounds
! // outside our max sound limit
! for(S32 i = NumSources; i < gPlayList.size(); )
! {
! SFXHandle &s = gPlayList[i];
! if(s->mSourceIndex != -1)
! {
! gSourceActive[s->mSourceIndex] = false;
! s->mSourceIndex = -1;
! }
! if(!s->mProfile->isLooping)
! gPlayList.erase_fast(i);
! else
! i++;
! }
! // now assign sources to all our sounds that need them:
! S32 firstFree = 0;
! S32 max = NumSources;
! if(max > gPlayList.size())
! max = gPlayList.size();
!
! for(S32 i = 0; i < max; i++)
! {
! SFXHandle &s = gPlayList[i];
! if(s->mSourceIndex == -1)
! {
! while(gSourceActive[firstFree])
! firstFree++;
! s->mSourceIndex = firstFree;
! gSourceActive[firstFree] = true;
! s->playOnSource();
! }
! else
! {
! // for other sources, just attenuate the gain.
! s->updateGain();
! }
! }
! }
!
! void SFXObject::setListenerParams(Point pos, Point velocity)
! {
! if(!gSFXValid)
! return;
!
! mListenerPosition = pos;
! mListenerVelocity = velocity;
! alListener3f(AL_POSITION, pos.x, pos.y, -mMaxDistance/2);
! }
!
! void SFXObject::shutdown()
! {
! if(!gSFXValid)
! return;
!
! alDeleteBuffers(NumSFXBuffers, gBuffers);
! alcMakeContextCurrent(NULL);
! alcDestroyContext(gContext);
! alcCloseDevice(gDevice);
! }
!
! };
!
! #else
!
! using namespace TNL;
!
! namespace Zap
! {
!
! Point SFXObject::mListenerPosition;
! Point SFXObject::mListenerVelocity;
! F32 SFXObject::mMaxDistance = 500;
!
! SFXObject::SFXObject(U32 sfxIndex, F32 gain, bool looping)
! {
! }
!
! SFXObject::SFXObject(U32 sfxIndex, Point position, Point velocity, F32 gain, bool looping)
! {
! }
!
! SFXObject::~SFXObject()
! {
!
! }
!
! void SFXObject::updateGain()
! {
! }
!
! void SFXObject::updateMovementParams()
! {
! }
!
! void SFXObject::playOnSource()
! {
! }
!
! void SFXObject::setGain(F32 gain)
! {
! }
!
! void SFXObject::setLooping(bool looping)
! {
! }
!
! void SFXObject::setMovementParams(Point position, Point velocity)
! {
! }
!
! void SFXObject::play()
! {
! }
!
! void SFXObject::stop()
! {
! }
!
! void SFXObject::init()
! {
! logprintf("No OpenAL support on this platform.");
! }
!
! void SFXObject::process()
! {
! }
!
! void SFXObject::setListenerParams(Point pos, Point velocity)
! {
! }
!
! void SFXObject::shutdown()
! {
! };
!
! };
!
! #endif
\ No newline at end of file
--- 1,456 ----
! //-----------------------------------------------------------------------------------
! //
! // Torque Network Library - ZAP example multiplayer vector graphics space game
! // Copyright (C) 2004 GarageGames.com, Inc.
! // For more information see http://www.opentnl.org
! //
! // 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.
! //
! // For use in products that are not compatible with the terms of the GNU
! // General Public License, alternative licensing options are available
! // from GarageGames.com.
! //
! // 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
! //
! //------------------------------------------------------------------------------------
!
! #include "sfx.h"
! #include "tnl.h"
! #include "tnlLog.h"
!
! #if defined (TNL_OS_WIN32) || defined (TNL_OS_LINUX)
!
! #include "alInclude.h"
!
! using namespace TNL;
!
! namespace Zap
! {
!
! static SFXProfile gSFXProfiles[] = {
! { "phaser.wav", false, 0.45f, false, 150, 600 },
! { "phaser_impact.wav", false, 0.7f, false, 150, 600 },
! { "ship_explode.wav", false, 1.0, false, 300, 1000 },
! { "flag_capture.wav", true, 0.45f, false, 0, 0 },
! { "flag_drop.wav", true, 0.45f, false, 0, 0 },
! { "flag_return.wav", true, 0.45f, false, 0, 0 },
! { "flag_snatch.wav", true, 0.45f, false, 0, 0 },
! { "teleport_in.wav", false, 1.0, false, 200, 500 },
! { "teleport_out.wav", false, 1.0, false, 200, 500 },
! { "bounce_wall.wav", false, 0.7f, false, 150, 600 },
! { "bounce_obj.wav", false, 0.7f, false, 150, 600 },
! { NULL, false, 0, false, 0, 0 },
! };
!
! static ALCdevice *gDevice = NULL;
! static ALCcontext *gContext = NULL;
! static bool gSFXValid = false;
!
! enum {
! NumSources = 16,
! };
!
! static ALuint gSources[NumSources];
! static bool gSourceActive[NumSources];
! Point SFXObject::mListenerPosition;
! Point SFXObject::mListenerVelocity;
! F32 SFXObject::mMaxDistance = 500;
!
! static ALuint gBuffers[NumSFXBuffers];
! static Vector<SFXHandle> gPlayList;
!
! SFXObject::SFXObject(U32 profileIndex, F32 gain, Point position, Point velocity)
! {
! mSFXIndex = profileIndex;
! mProfile = gSFXProfiles + profileIndex;
! mGain = gain;
! mPosition = position;
! mVelocity = velocity;
! mSourceIndex = -1;
! mPriority = 0;
! }
!
! RefPtr<SFXObject> SFXObject::play(U32 profileIndex, F32 gain)
! {
! RefPtr<SFXObject> ret = new SFXObject(profileIndex, gain, Point(), Point());
! ret->play();
! return ret;
! }
!
! RefPtr<SFXObject> SFXObject::play(U32 profileIndex, Point position, Point velocity, F32 gain)
! {
! RefPtr<SFXObject> ret = new SFXObject(profileIndex, gain, position, velocity);
! ret->play();
! return ret;
! }
!
! SFXObject::~SFXObject()
! {
!
! }
!
! void SFXObject::updateGain()
! {
! ALuint source = gSources[mSourceIndex];
! F32 gain = mGain;
!
! if(!mProfile->isRelative)
! {
! F32 distance = (mListenerPosition - mPosition).len();
! if(distance > mProfile->fullGainDistance)
! {
! if(distance < mProfile->zeroGainDistance)
! gain *= (mProfile->fullGainDistance - distance) /
! (mProfile->zeroGainDistance - mProfile->fullGainDistance);
! else
! gain = 0.0f;
! }
! else
! gain = 1.0f;
! }
! else
! gain = 1.0f;
!
! alSourcef(source, AL_GAIN, gain * mProfile->gainScale);
! }
!
! void SFXObject::updateMovementParams()
! {
! ALuint source = gSources[mSourceIndex];
! if(mProfile->isRelative)
! {
! alSourcei(source, AL_SOURCE_RELATIVE, true);
! alSource3f(source, AL_POSITION, 0, 0, 0);
! //alSource3f(source, AL_VELOCITY, 0, 0, 0);
! }
! else
! {
! alSourcei(source, AL_SOURCE_RELATIVE, false);
! alSource3f(source, AL_POSITION, mPosition.x, mPosition.y, 0);
! //alSource3f(source, AL_VELOCITY, mVelocity.x, mVelocity.y, 0);
! }
! }
!
! void SFXObject::playOnSource()
! {
! ALuint source = gSources[mSourceIndex];
! alSourceStop(source);
! alSourcei(source, AL_BUFFER, gBuffers[mSFXIndex]);
! alSourcei(source, AL_LOOPING, mProfile->isLooping);
! updateMovementParams();
!
! updateGain();
! alSourcePlay(source);
! }
!
! void SFXObject::setGain(F32 gain)
! {
! mGain = gain;
! if(mSourceIndex != -1)
! updateGain();
! }
!
! void SFXObject::setMovementParams(Point position, Point velocity)
! {
! mPosition = position;
! mVelocity = velocity;
! if(mSourceIndex != -1)
! updateMovementParams();
! }
!
! void SFXObject::play()
! {
! if(mSourceIndex != -1)
! return;
! else
! {
! // see if it's on the play list:
! S32 i;
! for(i = 0; i < gPlayList.size(); i++)
! if(gPlayList[i] == this)
! return;
! gPlayList.push_back(this);
! }
! }
!
! void SFXObject::stop()
! {
! // remove from the play list, if this sound is playing:
! if(mSourceIndex != -1)
! {
! alSourceStop(gSources[mSourceIndex]);
! mSourceIndex = -1;
! }
! for(S32 i = 0; i < gPlayList.size(); i++)
! {
! if(gPlayList[i] == this)
! {
! gPlayList.erase(i);
! return;
! }
! }
! }
!
! void SFXObject::init()
! {
! gDevice = alcOpenDevice((ALubyte *) "DirectSound3D");
! if(!gDevice)
! {
! logprintf("Failed to intitialize OpenAL.");
! return;
! }
!
! static int contextData[][2] =
! {
! {ALC_FREQUENCY, 11025},
! {0,0} // Indicate end of list...
! };
!
! gContext = alcCreateContext(gDevice, (ALCint*)contextData);
! alcMakeContextCurrent(gContext);
!
! alGetError();
!
! alDistanceModel(AL_NONE);
!
! // load up all the sound buffers
! alGenBuffers(NumSFXBuffers, gBuffers);
!
! if(alGetError() != AL_NO_ERROR)
! return;
!
! alGenSources(NumSources, gSources);
!
! for(U32 i = 0; i < NumSFXBuffers; i++)
! {
! if(!gSFXProfiles[i].fileName)
! break;
!
! ALsizei size,freq;
! ALenum format;
! ALvoid *data;
! ALboolean loop;
!
! alutLoadWAVFile((ALbyte *) gSFXProfiles[i].fileName, &format, &data, &size, &freq, &loop);
! if(alGetError() != AL_NO_ERROR)
! return;
! alBufferData(gBuffers[i], format, data, size, freq);
! alutUnloadWAV(format, data, size, freq);
! if(alGetError() != AL_NO_ERROR)
! return;
! }
! gSFXValid = true;
! }
!
! void SFXObject::process()
! {
! if(!gSFXValid)
! return;
!
! // ok, so we have a list of currently "playing" sounds, which is
! // unbounded in length, but only the top NumSources actually have sources
! // associtated with them. Sounds are prioritized on a 0-1 scale
! // based on type and distance.
! // Each time through the main loop, newly played sounds are placed
! // on the process list. When SFXProcess is called, any finished sounds
! // are retired from the list, and then it prioritizes and sorts all
! // the remaining sounds. For any sounds from 0 to NumSources that don't
! // have a current source, they grab one of the sources not used by the other
! // top sounds. At this point, any sound that is not looping, and is
! // not in the active top list is retired.
!
! // ok, look through all the currently playing sources and see which
! // ones need to be retired:
!
! for(S32 i = 0; i < NumSources; i++)
! {
! ALint state;
! alGetSourcei(gSources[i], AL_SOURCE_STATE, &state);
! gSourceActive[i] = state != AL_STOPPED && state != AL_INITIAL;
! }
! for(S32 i = 0; i < gPlayList.size(); )
! {
! SFXHandle &s = gPlayList[i];
! if(s->mSourceIndex != -1 && !gSourceActive[s->mSourceIndex])
! {
! // this sound was playing; now it is stopped,
! // so remove it from the list.
! s->mSourceIndex = -1;
! gPlayList.erase_fast(i);
! }
! else
! {
! // compute a priority for this sound.
! if(!s->mProfile->isRelative)
! s->mPriority = (500 - (s->mPosition - mListenerPosition).len()) / 500.0f;
! else
! s->mPriority = 1.0;
! i++;
! }
! }
! // now, bubble sort all the sounds up the list:
! // we choose bubble sort, because the list should
! // have a lot of frame-to-frame coherency, making the
! // sort most often O(n)
! for(S32 i = 1; i < gPlayList.size(); i++)
! {
! F32 priority = gPlayList[i]->mPriority;
! for(S32 j = i - 1; j >= 0; j--)
! {
! if(priority > gPlayList[j]->mPriority)
! {
! SFXHandle temp = gPlayList[j];
! gPlayList[j] = gPlayList[j+1];
! gPlayList[j+1] = temp;
! }
! }
! }
! // last, release any sources and get rid of non-looping sounds
! // outside our max sound limit
! for(S32 i = NumSources; i < gPlayList.size(); )
! {
! SFXHandle &s = gPlayList[i];
! if(s->mSourceIndex != -1)
! {
! gSourceActive[s->mSourceIndex] = false;
! s->mSourceIndex = -1;
! }
! if(!s->mProfile->isLooping)
! gPlayList.erase_fast(i);
! else
! i++;
! }
! // now assign sources to all our sounds that need them:
! S32 firstFree = 0;
! S32 max = NumSources;
! if(max > gPlayList.size())
! max = gPlayList.size();
!
! for(S32 i = 0; i < max; i++)
! {
! SFXHandle &s = gPlayList[i];
! if(s->mSourceIndex == -1)
! {
! while(gSourceActive[firstFree])
! firstFree++;
! s->mSourceIndex = firstFree;
! gSourceActive[firstFree] = true;
! s->playOnSource();
! }
! else
! {
! // for other sources, just attenuate the gain.
! s->updateGain();
! }
! }
! }
!
! void SFXObject::setListenerParams(Point pos, Point velocity)
! {
! if(!gSFXValid)
! return;
!
! mListenerPosition = pos;
! mListenerVelocity = velocity;
! alListener3f(AL_POSITION, pos.x, pos.y, -mMaxDistance/2);
! }
!
! void SFXObject::shutdown()
! {
! if(!gSFXValid)
! return;
!
! alDeleteBuffers(NumSFXBuffers, gBuffers);
! alcMakeContextCurrent(NULL);
! alcDestroyContext(gContext);
! alcCloseDevice(gDevice);
! }
!
! };
!
! #else
!
! using namespace TNL;
!
! namespace Zap
! {
!
! Point SFXObject::mListenerPosition;
! Point SFXObject::mListenerVelocity;
! F32 SFXObject::mMaxDistance = 500;
!
! SFXObject::SFXObject(U32 sfxIndex, F32 gain, bool looping)
! {
! }
!
! SFXObject::SFXObject(U32 sfxIndex, Point position, Point velocity, F32 gain, bool looping)
! {
! }
!
! SFXObject::~SFXObject()
! {
!
! }
!
! void SFXObject::updateGain()
! {
! }
!
! void SFXObject::updateMovementParams()
! {
! }
!
! void SFXObject::playOnSource()
! {
! }
!
! void SFXObject::setGain(F32 gain)
! {
! }
!
! void SFXObject::setLooping(bool looping)
! {
! }
!
! void SFXObject::setMovementParams(Point position, Point velocity)
! {
! }
!
! void SFXObject::play()
! {
! }
!
! void SFXObject::stop()
! {
! }
!
! void SFXObject::init()
! {
! logprintf("No OpenAL support on this platform.");
! }
!
! void SFXObject::process()
! {
! }
!
! void SFXObject::setListenerParams(Point pos, Point velocity)
! {
! }
!
! void SFXObject::shutdown()
! {
! };
!
! };
!
! #endif
Index: game.h
===================================================================
RCS file: /cvsroot/opentnl/tnl/zap/game.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** game.h 20 Apr 2004 18:40:19 -0000 1.2
--- game.h 20 Apr 2004 19:25:48 -0000 1.3
***************
*** 1,189 ****
! //-----------------------------------------------------------------------------------
! //
! // Torque Network Library - ZAP example multiplayer vector graphics space game
! // Copyright (C) 2004 GarageGames.com, Inc.
! // For more information see http://www.opentnl.org
! //
! // 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.
! //
! // For use in products that are not compatible with the terms of the GNU
! // General Public License, alternative licensing options are available
! // from GarageGames.com.
! //
! // 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
! //
! //------------------------------------------------------------------------------------
!
! #ifndef _GAME_H_
! #define _GAME_H_
!
! #include "point.h"
! #include "gameConnection.h"
! #include "../tnl/tnlNetObject.h"
! #include "gridDB.h"
!
! ///
! /// Zap - a 2D space game demonstrating the full capabilities of the
! /// Torque Network Library.
! ///
! /// The Zap example game is a 2D vector-graphics game that utilizes
! /// some of the more advanced features of the TNL. Zap also demonstrates
! /// the use of client-side prediction, and interpolation to present
! /// a consistent simulation to clients over a connection with perceptible
! /// latency.
! ///
! /// Zap can run in 3 modes - as a client, a client and server, or a dedicated
! /// server. The dedicated server option is available only as a launch
! /// parameter from the command line.
! ///
! /// If it is run as a client, Zap uses the GLUT library to perform
! /// cross-platform window intialization, event processing and OpenGL setup.
! ///
! /// Zap implements a simple game framework. The GameObject class is
! /// the root class for all of the various objects in the Zap world, including
! /// Ship, Barrier and Projectile instances. The Game class, which is instanced
! /// once for the client and once for the server, manages the current
! /// list of GameObject instances.
! ///
! /// Zap clients can connect to servers directly that are on the same LAN
! /// or for which the IP address is known. Zap is also capable of talking
! /// to the TNL master server and using its arranged connection functionality
! /// to talk to servers.
! ///
! /// The simplified user interface for Zap is managed entirely through
! /// subclasses of the UserInterface class. Each UserInterface subclass
! /// represents one "screen" in the UI. The GameUserInterface is the most complicated,
! /// being responsible for the user interface while the client is actually
! /// playing a game. The only other somewhat complicated UI is the
! /// QueryServersUserInterface class, which implements a full server browser
! /// for choosing from a list of LAN and master server queried servers.
! ///
! ///
! namespace Zap
! {
!
! class MasterServerConnection;
! class GameNetInterface;
! class GameType;
!
! /// Base class for server and client Game subclasses. The Game
! /// base class manages all the objects in the game simulation on
! /// either the server or the client, and is responsible for
! /// managing the passage of time as well as rendering.
! class Game
! {
! protected:
! U32 mLastIdleTime;
! U32 mNextMasterTryTime;
! F32 mGridSize;
!
! struct DeleteRef
! {
! GameO...
[truncated message content] |