Initial commit.
This commit is contained in:
commit
18b7ce6bc9
|
@ -0,0 +1,6 @@
|
|||
[submodule "zlib"]
|
||||
path = zlib
|
||||
url = https://github.com/madler/zlib
|
||||
[submodule "enet"]
|
||||
path = enet
|
||||
url = https://github.com/rna88/enet
|
|
@ -0,0 +1,27 @@
|
|||
## Irrnet
|
||||
|
||||
An updated version of the (irrNetLite)[http://irrlicht.sourceforge.net/forum/viewtopic.php?f=6&t=22658] networking library compiled against recent versions of (enet)[https://github.com/lsalzman/enet] and (zlib)[https://github.com/madler/zlib].
|
||||
|
||||
## Compiling for Linux
|
||||
|
||||
When cloning use the `--recurse-submodules` flag to retrieve the enet and zlib libraries needed by the project:
|
||||
|
||||
`git clone --recurse-submodules https://github.com/rna88/irrnet.git`
|
||||
|
||||
Then run `make` in the `source/` directory to build the library.
|
||||
|
||||
## Building examples
|
||||
|
||||
Navigate to `examples/` and run:
|
||||
|
||||
`./linux_buildAllExamples.sh`
|
||||
|
||||
or to build them with optimizations:
|
||||
|
||||
`./linux_buildAllExamples.sh release`
|
||||
|
||||
The compiled binaries will be found in `examples/bin/`
|
||||
|
||||
|
||||
|
||||
Original code by Ahmed Hilali.
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 7900e72b709798ac285431bf1860014c6e1caf91
|
|
@ -0,0 +1,28 @@
|
|||
CXX = g++
|
||||
Target := Example1
|
||||
TargetPath := ../bin/
|
||||
Sources := main.cpp
|
||||
|
||||
CXXINCS = -I../../include/
|
||||
|
||||
#ifndef NDEBUG
|
||||
CXXFLAGS_D = -g -Wall
|
||||
#else
|
||||
CXXFLAGS_R = -fexpensive-optimizations -O3
|
||||
#endif
|
||||
|
||||
LDIR =../../lib/
|
||||
LIBS = -L$(LDIR) -lirrnet
|
||||
|
||||
debug: main.cpp
|
||||
$(CXX) $(CXXFLAGS_D) $(CXXINCS) -o $(Target) $(Sources) $(LIBS)
|
||||
mv $(Target) $(TargetPath)
|
||||
|
||||
release: main.cpp
|
||||
$(CXX) $(CXXFLAGS_R) $(CXXINCS) -o $(Target) $(Sources) $(LIBS)
|
||||
mv $(Target) $(TargetPath)
|
||||
|
||||
clean:
|
||||
rm -f *.o $(TargetPath)$(Target)
|
||||
|
||||
.PHONY: clean debug release
|
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
Example 1: Packet Identification.
|
||||
|
||||
In this example I will expain the basics of packet identification.
|
||||
For a more basic introduction please refer to Tutorial.cpp first.
|
||||
(Recommended)
|
||||
*/
|
||||
|
||||
// Do the usual things here.
|
||||
#include <irrNet.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace irr;
|
||||
|
||||
#pragma comment(lib, "irrNetLite.lib")
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
|
||||
// Now, in this example, I will teach you the basics of packet
|
||||
// identification. What is packet identification? For instance,
|
||||
// lets say the client sends 3 floating point values to the server,
|
||||
// how will the server now if these represent a position, a rotation,
|
||||
// or something completely different? How will it even know these
|
||||
// are floating point values and not integers, or maybe a 12-byte
|
||||
// string? Obviously, we need some kind of mechanism to define this.
|
||||
// So in this example, we are going to define a few basic packet
|
||||
// types, that let us differentiate between the different kinds of
|
||||
// information coming into our client/server.
|
||||
|
||||
// I will start off by creating an enum that holds a simple id
|
||||
// for each of our packet types. (Note, you don't have to
|
||||
// explicitly set the values like I do, I am just doing that
|
||||
// for clarity.)
|
||||
enum E_PACKET_TYPE
|
||||
{
|
||||
EPT_ROTATION = 1,
|
||||
EPT_POWER = 2,
|
||||
EPT_MESSAGE = 3
|
||||
};
|
||||
|
||||
// In this example we will create 2 different callback classes, one
|
||||
// for the clients and one for the server. We will have an imaginary
|
||||
// cannon on the server, and the clients can send messages to change
|
||||
// it's angle and power.
|
||||
|
||||
// The server callback.
|
||||
class ServerNetCallback : public net::INetCallback
|
||||
{
|
||||
// We will store a pointer to the net manager.
|
||||
net::INetManager* netManager;
|
||||
|
||||
// Here we will store the cannon's power and angle.
|
||||
// Remember that f32 is just a typedef for float.
|
||||
f32 cannonPower;
|
||||
f32 cannonAngle;
|
||||
public:
|
||||
ServerNetCallback(net::INetManager* netManagerIn) : netManager(netManagerIn) {}
|
||||
|
||||
|
||||
// Our handlePacket function.
|
||||
virtual void handlePacket(net::SInPacket& packet)
|
||||
{
|
||||
// The packets will use a single char to store
|
||||
// the packet identifier, remember to use the
|
||||
// smallest possible datatype for storing your
|
||||
// packet identifiers. c8 is a typedef for char.
|
||||
c8 packetid;
|
||||
packet >> packetid;
|
||||
|
||||
// Here we will switch based on the packet id.
|
||||
switch((E_PACKET_TYPE)packetid)
|
||||
{
|
||||
case EPT_ROTATION:
|
||||
// We obtain the cannon angle from the packet.
|
||||
packet >> cannonAngle;
|
||||
std::cout << "The cannon angle is now " << cannonAngle << std::endl;
|
||||
break;
|
||||
case EPT_POWER:
|
||||
// Same here.
|
||||
packet >> cannonPower;
|
||||
std::cout << "The cannon power is now " << cannonPower << std::endl;
|
||||
break;
|
||||
case EPT_MESSAGE:
|
||||
// Now this is a special case (Pun intended, or is it even a pun?... nevermind),
|
||||
// The client has sent us a message as a string, so we will just print that
|
||||
// to the console.
|
||||
core::stringc message;
|
||||
packet >> message;
|
||||
|
||||
// We can obtain a unique "player id" from a packet identifying the client that
|
||||
// sent it. More details about the player id in a later example, for now we will
|
||||
// just print it out with the message so we know whos saying what.
|
||||
std::cout << "Client " << packet.getPlayerId() << " says: " << message.c_str();
|
||||
std::cout << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
// After handling a packet, we will send an updated status of the cannon to all clients.
|
||||
net::SOutPacket rotationPacket;
|
||||
|
||||
// The packet id is the first thing that goes in a packet. Note that I am casting it to a char,
|
||||
// because that is what we want to store it as, to save space. Be careful to use the same types
|
||||
// when sending and receiving, don't send as a char and receive as an int, it will cause trouble.
|
||||
rotationPacket << (c8)EPT_ROTATION;
|
||||
rotationPacket << cannonAngle;
|
||||
|
||||
// Send the packet to all connected clients.
|
||||
netManager->sendOutPacket(rotationPacket);
|
||||
|
||||
// Send a power update too.
|
||||
net::SOutPacket powerPacket;
|
||||
powerPacket << (c8)EPT_POWER;
|
||||
powerPacket << cannonPower;
|
||||
netManager->sendOutPacket(powerPacket);
|
||||
}
|
||||
};
|
||||
|
||||
// The client callback.
|
||||
class ClientNetCallback : public net::INetCallback
|
||||
{
|
||||
public:
|
||||
// Our handlePacket function.
|
||||
virtual void handlePacket(net::SInPacket& packet)
|
||||
{
|
||||
// Just like the server, we obtain the packet id and print
|
||||
// the information based on the packet we received. I hope the
|
||||
// rest of this function is self-explanatory.
|
||||
c8 packetid;
|
||||
packet >> packetid;
|
||||
|
||||
switch((E_PACKET_TYPE)packetid)
|
||||
{
|
||||
case EPT_ROTATION:
|
||||
f32 cannonAngle;
|
||||
packet >> cannonAngle;
|
||||
std::cout << "Server says that the cannon angle is now " << cannonAngle << std::endl;
|
||||
break;
|
||||
case EPT_POWER:
|
||||
f32 cannonPower;
|
||||
packet >> cannonPower;
|
||||
std::cout << "Server says that the cannon power is now " << cannonPower << std::endl;
|
||||
break;
|
||||
default:
|
||||
// We don't care about any other types, so we catch them here and break.
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// Ask the user whether they want to be the server or a client.
|
||||
std::cout << "Client (c) or Server (s)?";
|
||||
char i;
|
||||
std::cin >> i;
|
||||
|
||||
// If they typed 's' they are the server else they are the client.
|
||||
if(i == 's')
|
||||
{
|
||||
// Create an irrNetLite server.
|
||||
net::INetManager* netManager = net::createIrrNetServer(0);
|
||||
|
||||
// Pass in a server specific net callback.
|
||||
ServerNetCallback* serverCallback = new ServerNetCallback(netManager);
|
||||
netManager->setNetCallback(serverCallback);
|
||||
// Here we update like usual, most of the logic is in the callback.
|
||||
while(netManager->getConnectionStatus() != net::EICS_FAILED)
|
||||
netManager->update(1000);
|
||||
|
||||
// Delete everything.
|
||||
delete netManager;
|
||||
delete serverCallback;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a client and pass in the client callback.
|
||||
// You may want to change the ip address to a remote one and experiment
|
||||
// with connecting to a remote host.
|
||||
ClientNetCallback* clientCallback = new ClientNetCallback();
|
||||
net::INetManager* netManager = net::createIrrNetClient(clientCallback, "127.0.0.1");
|
||||
|
||||
// Print a simple menu.
|
||||
std::cout << "Example 1. What would you like to do?" << std::endl
|
||||
<< "1. Change the cannon rotation." << std::endl
|
||||
<< "2. Change the cannon power." << std::endl
|
||||
<< "3. Send a message." << std::endl;
|
||||
|
||||
// Take the input.
|
||||
char i = 0;
|
||||
std::cin >> i;
|
||||
|
||||
// Switch based on input.
|
||||
switch(i)
|
||||
{
|
||||
case '1':
|
||||
{
|
||||
// Here we create a rotation packet and send it to the server.
|
||||
net::SOutPacket rotationPacket;
|
||||
rotationPacket << (c8)EPT_ROTATION; // Remember to cast to the correct type.
|
||||
|
||||
// Ask for the rotation.
|
||||
f32 rotation;
|
||||
std::cout << "Please enter a rotation: ";
|
||||
std::cin >> rotation;
|
||||
rotationPacket << rotation;
|
||||
netManager->sendOutPacket(rotationPacket);
|
||||
break;
|
||||
}
|
||||
case '2':
|
||||
{
|
||||
// And here we create a power packet and send it to the server.
|
||||
net::SOutPacket powerPacket;
|
||||
powerPacket << (c8)EPT_POWER; // Remember to cast to the correct type.
|
||||
// Ask for the power.
|
||||
f32 power;
|
||||
std::cout << "Please enter the power: ";
|
||||
std::cin >> power;
|
||||
powerPacket << power;
|
||||
netManager->sendOutPacket(powerPacket);
|
||||
break;
|
||||
}
|
||||
case '3':
|
||||
{
|
||||
// We'll also send the server a message in the form of a string.
|
||||
net::SOutPacket messagePacket;
|
||||
messagePacket << (c8)EPT_MESSAGE; // Remember to cast to the correct type.
|
||||
// Ask for the message.
|
||||
char message[512] = {};
|
||||
std::cout << "Please enter a message:" << std::endl;
|
||||
std::cin >> message;
|
||||
messagePacket << message;
|
||||
netManager->sendOutPacket(messagePacket);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Here is the update loop, we will exit if there is a connection problem.
|
||||
while(netManager->getConnectionStatus() != net::EICS_FAILED)
|
||||
{
|
||||
// Here we update.
|
||||
netManager->update(1000);
|
||||
}
|
||||
|
||||
// Clean up.
|
||||
delete netManager;
|
||||
delete clientCallback;
|
||||
}
|
||||
|
||||
// And we're done, return 0 and make like a banana.
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
CXX = g++
|
||||
Target := Example2
|
||||
TargetPath := ../bin/
|
||||
Sources := main.cpp
|
||||
|
||||
CXXINCS = -I../../include/
|
||||
|
||||
#ifndef NDEBUG
|
||||
CXXFLAGS_D = -g -Wall
|
||||
#else
|
||||
CXXFLAGS_R = -fexpensive-optimizations -O3
|
||||
#endif
|
||||
|
||||
LDIR =../../lib/
|
||||
LIBS = -L$(LDIR) -lirrnet
|
||||
|
||||
debug: main.cpp
|
||||
$(CXX) $(CXXFLAGS_D) $(CXXINCS) -o $(Target) $(Sources) $(LIBS)
|
||||
mv $(Target) $(TargetPath)
|
||||
|
||||
release: main.cpp
|
||||
$(CXX) $(CXXFLAGS_R) $(CXXINCS) -o $(Target) $(Sources) $(LIBS)
|
||||
mv $(Target) $(TargetPath)
|
||||
|
||||
clean:
|
||||
rm -f *.o $(TargetPath)$(Target)
|
||||
|
||||
.PHONY: clean debug release
|
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
Example 2: Client management.
|
||||
|
||||
In this example I will demonstrate client management.
|
||||
For a more basic introduction please refer to Tutorial.cpp first.
|
||||
(Recommended)
|
||||
*/
|
||||
|
||||
// Do the usual things here.
|
||||
#include <irrNet.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace irr;
|
||||
|
||||
#pragma comment(lib, "irrNetLite.lib")
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
|
||||
// In this tutorial, I will show you how to kick/ban clients,
|
||||
// set a limit on how many clients can join a server, and
|
||||
// respond when a client connects/disconnects.
|
||||
|
||||
// Our server callback will be doing a little more than just
|
||||
// handling packets this time. We will override 2 more virtual
|
||||
// methods, onConnect and onDisconnect, that will notify us
|
||||
// with the player id of the client that has just connected or
|
||||
// disconnected. What is a player id? A player id is a unique
|
||||
// number that irrNetLite assigns to a client when they connect
|
||||
// to the server. The ids will start at 1 and grow until there
|
||||
// are no available slots left. Ids are not specific to a
|
||||
// computer or ip address, and are re-used when freed,
|
||||
// so if the client with played id 1 disconnects, and
|
||||
// a different one connects, he will take over that player id.
|
||||
// You may be thinking, "But how do I know which player is
|
||||
// connecting?" or, "How can I ban a player with a specific
|
||||
// ip address using this system?". These questions will be
|
||||
// answered in this tutorial, so pay close attention.
|
||||
class ServerNetCallback : public net::INetCallback
|
||||
{
|
||||
public:
|
||||
ServerNetCallback(net::INetManager* netManagerIn) : netManager(netManagerIn) {}
|
||||
|
||||
// Override the "onConnect" function, don't forget to get the method
|
||||
// signature correct. Whenever a fresh client connects, their brand
|
||||
// spanking new player id will be passed to this function. A "u16"
|
||||
// is a typedef for an unsigned short, incase you were wondering.
|
||||
virtual void onConnect(const u16 playerId)
|
||||
{
|
||||
// When a client connects we inform all other connected
|
||||
// clients that a client with that player id has connected.
|
||||
|
||||
// But first, lets say that we have already banned a few
|
||||
// clients from this server, and that we are keeping a list
|
||||
// of all the banned ip addresses. We can simply use
|
||||
// "getClientAddress()", to obtain the 32-bit representation
|
||||
// of the ip address and check it against the list.
|
||||
bool playerIsBanned = false;
|
||||
for(int i = 0;i < banList.size();++i)
|
||||
{
|
||||
if(netManager->getClientAddress(playerId) == banList[i])
|
||||
{
|
||||
playerIsBanned = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If the player is banned, send a message to all connected
|
||||
// clients that a player that is banned tried to connect
|
||||
// and then kick the naughty player.
|
||||
if(playerIsBanned)
|
||||
{
|
||||
net::SOutPacket packet;
|
||||
packet << "A player that is banned tried to connect, " \
|
||||
"so I kicked them.";
|
||||
netManager->sendOutPacket(packet);
|
||||
|
||||
// Kick the client by passing the player id.
|
||||
netManager->kickClient(playerId);
|
||||
}
|
||||
else // Else we tell everyone who connected.
|
||||
{
|
||||
// I am using a core::stringc here, it is very
|
||||
// similar to a std::string. You can use a std::string
|
||||
// if you want.
|
||||
net::SOutPacket packet;
|
||||
core::stringc message;
|
||||
message = "Client number ";
|
||||
message += playerId;
|
||||
message += " has just connected.";
|
||||
packet << message;
|
||||
netManager->sendOutPacket(packet);
|
||||
}
|
||||
}
|
||||
|
||||
// Similar to the onConnect function, except it happens when a
|
||||
// player disconnects. When this happens we will just report
|
||||
// which player has disconnected.
|
||||
virtual void onDisconnect(const u16 playerId)
|
||||
{
|
||||
net::SOutPacket packet;
|
||||
core::stringc message;
|
||||
message = "Client number ";
|
||||
message += playerId;
|
||||
message += " has just left the building.";
|
||||
packet << message;
|
||||
netManager->sendOutPacket(packet);
|
||||
}
|
||||
|
||||
// Handle the packets, as usual.
|
||||
virtual void handlePacket(net::SInPacket& packet)
|
||||
{
|
||||
// Now, we need a good reason to ban players.
|
||||
// Lets say I don't like people who talk alot,
|
||||
// so lets ban anyone who sends a greeting message
|
||||
// that is longer than 20 characters, else just
|
||||
// print the welcome message.
|
||||
core::stringc message;
|
||||
packet >> message;
|
||||
|
||||
// We can grab the unique player id of the player
|
||||
// that sent the packet from the packet itself.
|
||||
u16 playerId = packet.getPlayerId();
|
||||
|
||||
|
||||
if(message.size() > 20)
|
||||
{
|
||||
// Kick and ban the player by adding their address to our list.
|
||||
netManager->kickClient(playerId);
|
||||
u32 address = netManager->getClientAddress(playerId);
|
||||
banList.push_back(address);
|
||||
std::cout << "Player from " << address << " banned." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Print the message.
|
||||
std::cout << "Client " << playerId << " said " << message.c_str() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// An array of "u32", a typedef for unsigned int. This core::array is a
|
||||
// custom implementation of a dynamic array, very similar to std::vector.
|
||||
core::array<u32> banList;
|
||||
|
||||
// A pointer to the INetManager.
|
||||
net::INetManager* netManager;
|
||||
};
|
||||
|
||||
// The client callback.
|
||||
class ClientNetCallback : public net::INetCallback
|
||||
{
|
||||
public:
|
||||
// Our handlePacket function.
|
||||
virtual void handlePacket(net::SInPacket& packet)
|
||||
{
|
||||
// Very simple callback, just echo what the server says.
|
||||
core::stringc message;
|
||||
packet >> message;
|
||||
std::cout << "Server says: " << message.c_str() << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// Ask the user whether they want to be the server or a client.
|
||||
std::cout << "Client (c) or Server (s)?";
|
||||
char i;
|
||||
std::cin >> i;
|
||||
|
||||
// If they typed 's' they are the server else they are the client.
|
||||
if(i == 's')
|
||||
{
|
||||
// Create an irrNetLite server.
|
||||
net::INetManager* netManager = net::createIrrNetServer(0);
|
||||
|
||||
// Pass in a server specific net callback.
|
||||
ServerNetCallback* serverCallback = new ServerNetCallback(netManager);
|
||||
netManager->setNetCallback(serverCallback);
|
||||
|
||||
// Here we update like usual, most of the logic is in the callback.
|
||||
while(netManager->getConnectionStatus() != net::EICS_FAILED)
|
||||
netManager->update(1000);
|
||||
|
||||
// Delete everything.
|
||||
delete netManager;
|
||||
delete serverCallback;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a client and pass in the client callback.
|
||||
// You may want to change the ip address to a remote one and experiment
|
||||
// with connecting to a remote host, especially for this example as,
|
||||
// if you run all the clients from the same pc and ban one, you
|
||||
// won't be able to create anymore clients unless you restart the server.
|
||||
ClientNetCallback* clientCallback = new ClientNetCallback();
|
||||
net::INetManager* netManager = net::createIrrNetClient(clientCallback, "127.0.0.1");
|
||||
|
||||
// The clients in this example will simply send a custom greeting message
|
||||
// when they connect and then wait and poll for events.
|
||||
|
||||
// If there wasn't a problem connecting we will send a greeting message.
|
||||
if(netManager->getConnectionStatus() != net::EICS_FAILED)
|
||||
{
|
||||
// Print a simple menu.
|
||||
std::cout << "Example 2. Please enter a greeting message:" << std::endl;
|
||||
|
||||
// Take the input.
|
||||
std::string message;
|
||||
std::cin >> message;
|
||||
|
||||
// Send a packet with the message entered.
|
||||
net::SOutPacket packet;
|
||||
packet << message;
|
||||
netManager->sendOutPacket(packet);
|
||||
}
|
||||
|
||||
// Here is the update loop, we will exit if there is a connection problem.
|
||||
while(netManager->getConnectionStatus() != net::EICS_FAILED)
|
||||
{
|
||||
// Here we update.
|
||||
netManager->update(1000);
|
||||
}
|
||||
|
||||
// Clean up.
|
||||
delete netManager;
|
||||
delete clientCallback;
|
||||
}
|
||||
|
||||
// And we're done, return 0 and make like an egg.
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
CXX = g++
|
||||
Target := Tutorial
|
||||
TargetPath := ../bin/
|
||||
Sources := main.cpp
|
||||
|
||||
CXXINCS = -I../../include/
|
||||
|
||||
#ifndef NDEBUG
|
||||
CXXFLAGS_D = -g -Wall
|
||||
#else
|
||||
CXXFLAGS_R = -fexpensive-optimizations -O3
|
||||
#endif
|
||||
|
||||
LDIR =../../lib/
|
||||
LIBS = -L$(LDIR) -lirrnet
|
||||
|
||||
debug: main.cpp
|
||||
$(CXX) $(CXXFLAGS_D) $(CXXINCS) -o $(Target) $(Sources) $(LIBS)
|
||||
mv $(Target) $(TargetPath)
|
||||
|
||||
release: main.cpp
|
||||
$(CXX) $(CXXFLAGS_R) $(CXXINCS) -o $(Target) $(Sources) $(LIBS)
|
||||
mv $(Target) $(TargetPath)
|
||||
|
||||
clean:
|
||||
rm -f *.o $(TargetPath)$(Target)
|
||||
|
||||
.PHONY: clean debug release
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
Welcome to the simple, introductory tutorial for irrNetLite. This will show you the
|
||||
very basics of setting up a client and server, and sending and receiving packets.
|
||||
Because irrNetLite is so easy to use, I think you will not find many actual lines of
|
||||
code in this example, rather most of it is documentation.
|
||||
|
||||
For much more sophisticated use of irrNetLite, I recommend taking a look in the
|
||||
examples subdirectory.
|
||||
*/
|
||||
|
||||
// Include the main irrNet.h header for irrNetLite.
|
||||
#include <irrNet.h>
|
||||
#include <iostream>
|
||||
|
||||
// irrNetLite resides within the irr::net:: namespace, therefore,
|
||||
// we use "using namespace irr" here to simplify things.
|
||||
// Alternatively you can add "using namespace net" after
|
||||
// this so that net:: doesn't have to be used either.
|
||||
using namespace irr;
|
||||
|
||||
// These pragmas are for MSVC users, they ease the linking of librarys.
|
||||
// "ws2_32.lib" is part of the Windows Platform SDK and must be linked
|
||||
// in when compiling on windows. On linux/mac machines, these pragmas
|
||||
// will simply be ignored, and the linking to irrNetLite static lib
|
||||
// should be performed by a makefile.
|
||||
#pragma comment(lib, "irrNetLite.lib")
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
|
||||
// You must derive a class from INetCallback and override the
|
||||
// "handlePacket" method. When a packet is received it will be
|
||||
// passed to this function, and you may dissect it as you wish.
|
||||
// If this is the server you may retrieve the player ID using
|
||||
// packet.getPlayerId().
|
||||
class MyNetCallback : public net::INetCallback
|
||||
{
|
||||
public:
|
||||
virtual void handlePacket(net::SInPacket& packet)
|
||||
{
|
||||
// irrNetLite encryption is very easy to use! Just pass
|
||||
// a 16-byte (128-bit) string to encryptPacket/decryptPacket
|
||||
// to encrypt/decrypt a packet respectively. Do not try to
|
||||
// decrypt an un-encrypted packet or read from an encrypted
|
||||
// packet without decrypting it first or bad things will happen!
|
||||
packet.decryptPacket("hushthisissecret");
|
||||
|
||||
// irrNetLite compression is even easier! The ZLib library is used
|
||||
// here, just call compressPacket/decompressPacket to
|
||||
// compress/decompress a packet. Again, do not try to decompress
|
||||
// an un-compressed packet or read from a compressed packet without
|
||||
// decompressing it! Another thing to keep in mind is that you should
|
||||
// decompress and decrypt in the correct order. If you compressed a file
|
||||
// and then encrypted it when it was sent, you must decrypt it first
|
||||
// before trying to decompress it, same goes for the other order.
|
||||
packet.deCompressPacket();
|
||||
|
||||
// Extracting info from a received packet is simple. You can treat
|
||||
// the packet as an input stream, the >> operator is overloaded
|
||||
// and works for most built in types. The string class in irrNetLite
|
||||
// is a custom implementation not unlike the std::string. You can
|
||||
// also send and receive strings as "char*". Note that the "char*"
|
||||
// and stringc are interchangeable, you can send a stringc and
|
||||
// receive a char*, or vice-versa.
|
||||
core::stringc str;
|
||||
packet >> str;
|
||||
|
||||
// Support for a simple 3-dimensional vector class is there too. Both
|
||||
// vector3df and core::stringc are borrowed from Irrlicht and included
|
||||
// here for convenience.
|
||||
core::vector3df vec;
|
||||
packet >> vec;
|
||||
|
||||
// Here we are obtaining the last value from the packet. f32 is just a
|
||||
// typedef for float.
|
||||
f32 height;
|
||||
packet >> height;
|
||||
|
||||
// Print the values to the console.
|
||||
std::cout << "Message: " << str.c_str();
|
||||
std::cout << " Position: " << vec.X << " " << vec.Y << " " << vec.Z;
|
||||
std::cout << " Height: " << height << " ft";
|
||||
std::cout << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
// Ok, lets go from the start, int main()
|
||||
int main()
|
||||
{
|
||||
// Ask the user whether they want to be the server or a client.
|
||||
std::cout << "Client (c) or Server (s)?";
|
||||
char i;
|
||||
std::cin >> i;
|
||||
|
||||
// If they typed 's' they are the server else they are the client.
|
||||
if(i == 's')
|
||||
{
|
||||
// Create a server and pass in a new instance of our callback class. The default
|
||||
// port that clients can connect to is set to 45000.
|
||||
MyNetCallback* netCallback = new MyNetCallback();
|
||||
net::INetManager* netManager = net::createIrrNetServer(netCallback);
|
||||
|
||||
// Setting verbose to true makes irrNetLite spit out debug information to the console.
|
||||
netManager->setVerbose(true);
|
||||
|
||||
// While the connection is active (Not failed), we update the netManager.
|
||||
// Note that since this is a server the connection will pretty much always
|
||||
// be flagged as active, unless some error occured whilst creating the server.
|
||||
// A value of 1000 is passed to update to make it hang for a second and wait for
|
||||
// packets to arrive. (Recommended for servers, so you don't busy-loop).
|
||||
while(netManager->getConnectionStatus() != net::EICS_FAILED)
|
||||
netManager->update(1000);
|
||||
|
||||
// Don't forget to clean up!
|
||||
delete netManager;
|
||||
delete netCallback;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create an irrNet client, in this example we will just connect to the localhost
|
||||
// address ("127.0.0.1"), which basically means we are connecting to the same
|
||||
// computer the client is on. Note that we just pass a value of 0 as our
|
||||
// INetCallback, because the client in this example does no need to handle any
|
||||
// packets. You can safely pass a value of 0 if this is the case.
|
||||
net::INetManager* netManager = net::createIrrNetClient(0, "127.0.0.1");
|
||||
|
||||
// Enable debug messages.
|
||||
netManager->setVerbose(true);
|
||||
|
||||
// Here comes the fun part, while the client is connected we update the netManager
|
||||
// and ask it to wait 1 second (1000 milliseconds) for new packets to arrive before
|
||||
// returning. Since the client in this example doesn't actually receive any packets,
|
||||
// the only purpose of the update call is to leave a 1 second interval between each
|
||||
// packet we send.
|
||||
|
||||
int i = 0;
|
||||
// To send a packet, first you create an SOutPacket object.
|
||||
net::SOutPacket packet;
|
||||
|
||||
while(netManager->getConnectionStatus() != net::EICS_FAILED && i < 10 )
|
||||
{
|
||||
|
||||
// To send a packet, first you create an SOutPacket object.
|
||||
//net::SOutPacket packet;
|
||||
|
||||
// Then you can use the streaming operator << to add new data to it.
|
||||
packet << "Help I am stuck on a mountain!";
|
||||
|
||||
// You can even chain the << operators like so, just like with ostream.
|
||||
packet << core::vector3df(50.0f, 30.0f, 20.0f) << 50.0f;
|
||||
|
||||
// Compress the packet, not much to be said.
|
||||
packet.compressPacket();
|
||||
|
||||
// Encrypt the packet. Note that here we are just using a simple key
|
||||
// that is shared among the client and the server. In more sophisticated
|
||||
// implementations you may want to generate a random key on the server for
|
||||
// each client and send that using a shared key, then use the new key for
|
||||
// further communication. Remember that the key should be 16 characters
|
||||
// long, and obviously the client and server must share the same key.
|
||||
packet.encryptPacket("hushthisissecret");
|
||||
|
||||
// A simple call to "sendOutPacket" will send the packet to the server.
|
||||
netManager->sendOutPacket(packet);
|
||||
|
||||
netManager->update(1000);
|
||||
packet.clearData();
|
||||
i++;
|
||||
}
|
||||
|
||||
// When the connection disconnects (Or fails), the loop will terminate.
|
||||
// Remember to delete the netManager so that all the low level networking
|
||||
// stuff is cleaned up properly.
|
||||
delete netManager;
|
||||
}
|
||||
|
||||
// And we're done, return 0 and make like a tree.
|
||||
return 0;
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,15 @@
|
|||
#! /bin/bash
|
||||
[ -z $1 ] || TARGET=$1
|
||||
[ -z $TARGET ] && TARGET=debug
|
||||
for i in Tutorial Example* ; do
|
||||
echo "Building $i";
|
||||
pushd $i && make clean $TARGET;
|
||||
popd;
|
||||
done
|
||||
|
||||
|
||||
|
||||
|
||||
#g++ Tutorial.cpp -I../irrnet -L../lib -lirrnet -o Tutorial
|
||||
#g++ Example1.cpp -I../irrnet -L../lib -lirrnet -o Example1
|
||||
#g++ Example2.cpp -I../irrnet -L../lib -lirrnet -o Example2
|
|
@ -0,0 +1,411 @@
|
|||
// AES encryption class, based on work by Karl Malbrain, malbrain@yahoo.com,
|
||||
// original license shown here:
|
||||
|
||||
/*
|
||||
This work, including the source code, documentation
|
||||
and related data, is placed into the public domain.
|
||||
|
||||
The orginal author is Karl Malbrain.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY
|
||||
OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF
|
||||
MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE,
|
||||
ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE
|
||||
RESULTING FROM THE USE, MODIFICATION, OR
|
||||
REDISTRIBUTION OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
typedef unsigned char uchar;
|
||||
#include <string.h>
|
||||
#include <memory.h>
|
||||
|
||||
// AES only supports Nb=4
|
||||
#define Nb 4 // number of columns in the state & expanded key
|
||||
|
||||
#define Nk 4 // number of columns in a key
|
||||
#define Nr 10 // number of rounds in encryption
|
||||
|
||||
static const uchar Sbox[256] = { // forward s-box
|
||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
||||
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
|
||||
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
|
||||
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
|
||||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
|
||||
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
|
||||
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
|
||||
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
|
||||
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
|
||||
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
|
||||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
||||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
|
||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};
|
||||
|
||||
static const uchar InvSbox[256] = { // inverse s-box
|
||||
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
|
||||
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
|
||||
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
|
||||
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
|
||||
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
|
||||
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
|
||||
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
|
||||
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
|
||||
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
|
||||
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
|
||||
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
|
||||
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
|
||||
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
|
||||
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
|
||||
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
|
||||
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d};
|
||||
|
||||
// combined Xtimes2[Sbox[]]
|
||||
static const uchar Xtime2Sbox[256] = {
|
||||
0xc6, 0xf8, 0xee, 0xf6, 0xff, 0xd6, 0xde, 0x91, 0x60, 0x02, 0xce, 0x56, 0xe7, 0xb5, 0x4d, 0xec,
|
||||
0x8f, 0x1f, 0x89, 0xfa, 0xef, 0xb2, 0x8e, 0xfb, 0x41, 0xb3, 0x5f, 0x45, 0x23, 0x53, 0xe4, 0x9b,
|
||||
0x75, 0xe1, 0x3d, 0x4c, 0x6c, 0x7e, 0xf5, 0x83, 0x68, 0x51, 0xd1, 0xf9, 0xe2, 0xab, 0x62, 0x2a,
|
||||
0x08, 0x95, 0x46, 0x9d, 0x30, 0x37, 0x0a, 0x2f, 0x0e, 0x24, 0x1b, 0xdf, 0xcd, 0x4e, 0x7f, 0xea,
|
||||
0x12, 0x1d, 0x58, 0x34, 0x36, 0xdc, 0xb4, 0x5b, 0xa4, 0x76, 0xb7, 0x7d, 0x52, 0xdd, 0x5e, 0x13,
|
||||
0xa6, 0xb9, 0x00, 0xc1, 0x40, 0xe3, 0x79, 0xb6, 0xd4, 0x8d, 0x67, 0x72, 0x94, 0x98, 0xb0, 0x85,
|
||||
0xbb, 0xc5, 0x4f, 0xed, 0x86, 0x9a, 0x66, 0x11, 0x8a, 0xe9, 0x04, 0xfe, 0xa0, 0x78, 0x25, 0x4b,
|
||||
0xa2, 0x5d, 0x80, 0x05, 0x3f, 0x21, 0x70, 0xf1, 0x63, 0x77, 0xaf, 0x42, 0x20, 0xe5, 0xfd, 0xbf,
|
||||
0x81, 0x18, 0x26, 0xc3, 0xbe, 0x35, 0x88, 0x2e, 0x93, 0x55, 0xfc, 0x7a, 0xc8, 0xba, 0x32, 0xe6,
|
||||
0xc0, 0x19, 0x9e, 0xa3, 0x44, 0x54, 0x3b, 0x0b, 0x8c, 0xc7, 0x6b, 0x28, 0xa7, 0xbc, 0x16, 0xad,
|
||||
0xdb, 0x64, 0x74, 0x14, 0x92, 0x0c, 0x48, 0xb8, 0x9f, 0xbd, 0x43, 0xc4, 0x39, 0x31, 0xd3, 0xf2,
|
||||
0xd5, 0x8b, 0x6e, 0xda, 0x01, 0xb1, 0x9c, 0x49, 0xd8, 0xac, 0xf3, 0xcf, 0xca, 0xf4, 0x47, 0x10,
|
||||
0x6f, 0xf0, 0x4a, 0x5c, 0x38, 0x57, 0x73, 0x97, 0xcb, 0xa1, 0xe8, 0x3e, 0x96, 0x61, 0x0d, 0x0f,
|
||||
0xe0, 0x7c, 0x71, 0xcc, 0x90, 0x06, 0xf7, 0x1c, 0xc2, 0x6a, 0xae, 0x69, 0x17, 0x99, 0x3a, 0x27,
|
||||
0xd9, 0xeb, 0x2b, 0x22, 0xd2, 0xa9, 0x07, 0x33, 0x2d, 0x3c, 0x15, 0xc9, 0x87, 0xaa, 0x50, 0xa5,
|
||||
0x03, 0x59, 0x09, 0x1a, 0x65, 0xd7, 0x84, 0xd0, 0x82, 0x29, 0x5a, 0x1e, 0x7b, 0xa8, 0x6d, 0x2c
|
||||
};
|
||||
|
||||
// combined Xtimes3[Sbox[]]
|
||||
static const uchar Xtime3Sbox[256] = {
|
||||
0xa5, 0x84, 0x99, 0x8d, 0x0d, 0xbd, 0xb1, 0x54, 0x50, 0x03, 0xa9, 0x7d, 0x19, 0x62, 0xe6, 0x9a,
|
||||
0x45, 0x9d, 0x40, 0x87, 0x15, 0xeb, 0xc9, 0x0b, 0xec, 0x67, 0xfd, 0xea, 0xbf, 0xf7, 0x96, 0x5b,
|
||||
0xc2, 0x1c, 0xae, 0x6a, 0x5a, 0x41, 0x02, 0x4f, 0x5c, 0xf4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3f,
|
||||
0x0c, 0x52, 0x65, 0x5e, 0x28, 0xa1, 0x0f, 0xb5, 0x09, 0x36, 0x9b, 0x3d, 0x26, 0x69, 0xcd, 0x9f,
|
||||
0x1b, 0x9e, 0x74, 0x2e, 0x2d, 0xb2, 0xee, 0xfb, 0xf6, 0x4d, 0x61, 0xce, 0x7b, 0x3e, 0x71, 0x97,
|
||||
0xf5, 0x68, 0x00, 0x2c, 0x60, 0x1f, 0xc8, 0xed, 0xbe, 0x46, 0xd9, 0x4b, 0xde, 0xd4, 0xe8, 0x4a,
|
||||
0x6b, 0x2a, 0xe5, 0x16, 0xc5, 0xd7, 0x55, 0x94, 0xcf, 0x10, 0x06, 0x81, 0xf0, 0x44, 0xba, 0xe3,
|
||||
0xf3, 0xfe, 0xc0, 0x8a, 0xad, 0xbc, 0x48, 0x04, 0xdf, 0xc1, 0x75, 0x63, 0x30, 0x1a, 0x0e, 0x6d,
|
||||
0x4c, 0x14, 0x35, 0x2f, 0xe1, 0xa2, 0xcc, 0x39, 0x57, 0xf2, 0x82, 0x47, 0xac, 0xe7, 0x2b, 0x95,
|
||||
0xa0, 0x98, 0xd1, 0x7f, 0x66, 0x7e, 0xab, 0x83, 0xca, 0x29, 0xd3, 0x3c, 0x79, 0xe2, 0x1d, 0x76,
|
||||
0x3b, 0x56, 0x4e, 0x1e, 0xdb, 0x0a, 0x6c, 0xe4, 0x5d, 0x6e, 0xef, 0xa6, 0xa8, 0xa4, 0x37, 0x8b,
|
||||
0x32, 0x43, 0x59, 0xb7, 0x8c, 0x64, 0xd2, 0xe0, 0xb4, 0xfa, 0x07, 0x25, 0xaf, 0x8e, 0xe9, 0x18,
|
||||
0xd5, 0x88, 0x6f, 0x72, 0x24, 0xf1, 0xc7, 0x51, 0x23, 0x7c, 0x9c, 0x21, 0xdd, 0xdc, 0x86, 0x85,
|
||||
0x90, 0x42, 0xc4, 0xaa, 0xd8, 0x05, 0x01, 0x12, 0xa3, 0x5f, 0xf9, 0xd0, 0x91, 0x58, 0x27, 0xb9,
|
||||
0x38, 0x13, 0xb3, 0x33, 0xbb, 0x70, 0x89, 0xa7, 0xb6, 0x22, 0x92, 0x20, 0x49, 0xff, 0x78, 0x7a,
|
||||
0x8f, 0xf8, 0x80, 0x17, 0xda, 0x31, 0xc6, 0xb8, 0xc3, 0xb0, 0x77, 0x11, 0xcb, 0xfc, 0xd6, 0x3a
|
||||
};
|
||||
|
||||
// modular multiplication tables
|
||||
// based on:
|
||||
|
||||
// Xtime2[x] = (x & 0x80 ? 0x1b : 0) ^ (x + x)
|
||||
// Xtime3[x] = x^Xtime2[x];
|
||||
|
||||
static const uchar Xtime2[256] = {
|
||||
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
|
||||
0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
|
||||
0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
|
||||
0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
|
||||
0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
|
||||
0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
|
||||
0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
|
||||
0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
|
||||
0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
|
||||
0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
|
||||
0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
|
||||
0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
|
||||
0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
|
||||
0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
|
||||
0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
|
||||
0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5};
|
||||
|
||||
static const uchar Xtime9[256] = {
|
||||
0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
|
||||
0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
|
||||
0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
|
||||
0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc,
|
||||
0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01,
|
||||
0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
|
||||
0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a,
|
||||
0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa,
|
||||
0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
|
||||
0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b,
|
||||
0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0,
|
||||
0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
|
||||
0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed,
|
||||
0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d,
|
||||
0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
|
||||
0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46};
|
||||
|
||||
static const uchar XtimeB[256] = {
|
||||
0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
|
||||
0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
|
||||
0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
|
||||
0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2,
|
||||
0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f,
|
||||
0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
|
||||
0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4,
|
||||
0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54,
|
||||
0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
|
||||
0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e,
|
||||
0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5,
|
||||
0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
|
||||
0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68,
|
||||
0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8,
|
||||
0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
|
||||
0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3};
|
||||
|
||||
static const uchar XtimeD[256] = {
|
||||
0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
|
||||
0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
|
||||
0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
|
||||
0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20,
|
||||
0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26,
|
||||
0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
|
||||
0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d,
|
||||
0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d,
|
||||
0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
|
||||
0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41,
|
||||
0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a,
|
||||
0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
|
||||
0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc,
|
||||
0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c,
|
||||
0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
|
||||
0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97};
|
||||
|
||||
static const uchar XtimeE[256] = {
|
||||
0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
|
||||
0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
|
||||
0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
|
||||
0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61,
|
||||
0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7,
|
||||
0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
|
||||
0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c,
|
||||
0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc,
|
||||
0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
|
||||
0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb,
|
||||
0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0,
|
||||
0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
|
||||
0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
|
||||
0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
|
||||
0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
|
||||
0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d};
|
||||
|
||||
// exchanges columns in each of 4 rows
|
||||
// row0 - unchanged, row1- shifted left 1,
|
||||
// row2 - shifted left 2 and row3 - shifted left 3
|
||||
static void ShiftRows (uchar *state)
|
||||
{
|
||||
uchar tmp;
|
||||
|
||||
// just substitute row 0
|
||||
state[0] = Sbox[state[0]], state[4] = Sbox[state[4]];
|
||||
state[8] = Sbox[state[8]], state[12] = Sbox[state[12]];
|
||||
|
||||
// rotate row 1
|
||||
tmp = Sbox[state[1]], state[1] = Sbox[state[5]];
|
||||
state[5] = Sbox[state[9]], state[9] = Sbox[state[13]], state[13] = tmp;
|
||||
|
||||
// rotate row 2
|
||||
tmp = Sbox[state[2]], state[2] = Sbox[state[10]], state[10] = tmp;
|
||||
tmp = Sbox[state[6]], state[6] = Sbox[state[14]], state[14] = tmp;
|
||||
|
||||
// rotate row 3
|
||||
tmp = Sbox[state[15]], state[15] = Sbox[state[11]];
|
||||
state[11] = Sbox[state[7]], state[7] = Sbox[state[3]], state[3] = tmp;
|
||||
}
|
||||
|
||||
// restores columns in each of 4 rows
|
||||
// row0 - unchanged, row1- shifted right 1,
|
||||
// row2 - shifted right 2 and row3 - shifted right 3
|
||||
static void InvShiftRows (uchar *state)
|
||||
{
|
||||
uchar tmp;
|
||||
|
||||
// restore row 0
|
||||
state[0] = InvSbox[state[0]], state[4] = InvSbox[state[4]];
|
||||
state[8] = InvSbox[state[8]], state[12] = InvSbox[state[12]];
|
||||
|
||||
// restore row 1
|
||||
tmp = InvSbox[state[13]], state[13] = InvSbox[state[9]];
|
||||
state[9] = InvSbox[state[5]], state[5] = InvSbox[state[1]], state[1] = tmp;
|
||||
|
||||
// restore row 2
|
||||
tmp = InvSbox[state[2]], state[2] = InvSbox[state[10]], state[10] = tmp;
|
||||
tmp = InvSbox[state[6]], state[6] = InvSbox[state[14]], state[14] = tmp;
|
||||
|
||||
// restore row 3
|
||||
tmp = InvSbox[state[3]], state[3] = InvSbox[state[7]];
|
||||
state[7] = InvSbox[state[11]], state[11] = InvSbox[state[15]], state[15] = tmp;
|
||||
}
|
||||
|
||||
// recombine and mix each row in a column
|
||||
static void MixSubColumns (uchar *state)
|
||||
{
|
||||
uchar tmp[4 * Nb];
|
||||
|
||||
// mixing column 0
|
||||
tmp[0] = Xtime2Sbox[state[0]] ^ Xtime3Sbox[state[5]] ^ Sbox[state[10]] ^ Sbox[state[15]];
|
||||
tmp[1] = Sbox[state[0]] ^ Xtime2Sbox[state[5]] ^ Xtime3Sbox[state[10]] ^ Sbox[state[15]];
|
||||
tmp[2] = Sbox[state[0]] ^ Sbox[state[5]] ^ Xtime2Sbox[state[10]] ^ Xtime3Sbox[state[15]];
|
||||
tmp[3] = Xtime3Sbox[state[0]] ^ Sbox[state[5]] ^ Sbox[state[10]] ^ Xtime2Sbox[state[15]];
|
||||
|
||||
// mixing column 1
|
||||
tmp[4] = Xtime2Sbox[state[4]] ^ Xtime3Sbox[state[9]] ^ Sbox[state[14]] ^ Sbox[state[3]];
|
||||
tmp[5] = Sbox[state[4]] ^ Xtime2Sbox[state[9]] ^ Xtime3Sbox[state[14]] ^ Sbox[state[3]];
|
||||
tmp[6] = Sbox[state[4]] ^ Sbox[state[9]] ^ Xtime2Sbox[state[14]] ^ Xtime3Sbox[state[3]];
|
||||
tmp[7] = Xtime3Sbox[state[4]] ^ Sbox[state[9]] ^ Sbox[state[14]] ^ Xtime2Sbox[state[3]];
|
||||
|
||||
// mixing column 2
|
||||
tmp[8] = Xtime2Sbox[state[8]] ^ Xtime3Sbox[state[13]] ^ Sbox[state[2]] ^ Sbox[state[7]];
|
||||
tmp[9] = Sbox[state[8]] ^ Xtime2Sbox[state[13]] ^ Xtime3Sbox[state[2]] ^ Sbox[state[7]];
|
||||
tmp[10] = Sbox[state[8]] ^ Sbox[state[13]] ^ Xtime2Sbox[state[2]] ^ Xtime3Sbox[state[7]];
|
||||
tmp[11] = Xtime3Sbox[state[8]] ^ Sbox[state[13]] ^ Sbox[state[2]] ^ Xtime2Sbox[state[7]];
|
||||
|
||||
// mixing column 3
|
||||
tmp[12] = Xtime2Sbox[state[12]] ^ Xtime3Sbox[state[1]] ^ Sbox[state[6]] ^ Sbox[state[11]];
|
||||
tmp[13] = Sbox[state[12]] ^ Xtime2Sbox[state[1]] ^ Xtime3Sbox[state[6]] ^ Sbox[state[11]];
|
||||
tmp[14] = Sbox[state[12]] ^ Sbox[state[1]] ^ Xtime2Sbox[state[6]] ^ Xtime3Sbox[state[11]];
|
||||
tmp[15] = Xtime3Sbox[state[12]] ^ Sbox[state[1]] ^ Sbox[state[6]] ^ Xtime2Sbox[state[11]];
|
||||
|
||||
memcpy (state, tmp, sizeof(tmp));
|
||||
}
|
||||
|
||||
// restore and un-mix each row in a column
|
||||
static void InvMixSubColumns (uchar *state)
|
||||
{
|
||||
uchar tmp[4 * Nb];
|
||||
int i;
|
||||
|
||||
// restore column 0
|
||||
tmp[0] = XtimeE[state[0]] ^ XtimeB[state[1]] ^ XtimeD[state[2]] ^ Xtime9[state[3]];
|
||||
tmp[5] = Xtime9[state[0]] ^ XtimeE[state[1]] ^ XtimeB[state[2]] ^ XtimeD[state[3]];
|
||||
tmp[10] = XtimeD[state[0]] ^ Xtime9[state[1]] ^ XtimeE[state[2]] ^ XtimeB[state[3]];
|
||||
tmp[15] = XtimeB[state[0]] ^ XtimeD[state[1]] ^ Xtime9[state[2]] ^ XtimeE[state[3]];
|
||||
|
||||
// restore column 1
|
||||
tmp[4] = XtimeE[state[4]] ^ XtimeB[state[5]] ^ XtimeD[state[6]] ^ Xtime9[state[7]];
|
||||
tmp[9] = Xtime9[state[4]] ^ XtimeE[state[5]] ^ XtimeB[state[6]] ^ XtimeD[state[7]];
|
||||
tmp[14] = XtimeD[state[4]] ^ Xtime9[state[5]] ^ XtimeE[state[6]] ^ XtimeB[state[7]];
|
||||
tmp[3] = XtimeB[state[4]] ^ XtimeD[state[5]] ^ Xtime9[state[6]] ^ XtimeE[state[7]];
|
||||
|
||||
// restore column 2
|
||||
tmp[8] = XtimeE[state[8]] ^ XtimeB[state[9]] ^ XtimeD[state[10]] ^ Xtime9[state[11]];
|
||||
tmp[13] = Xtime9[state[8]] ^ XtimeE[state[9]] ^ XtimeB[state[10]] ^ XtimeD[state[11]];
|
||||
tmp[2] = XtimeD[state[8]] ^ Xtime9[state[9]] ^ XtimeE[state[10]] ^ XtimeB[state[11]];
|
||||
tmp[7] = XtimeB[state[8]] ^ XtimeD[state[9]] ^ Xtime9[state[10]] ^ XtimeE[state[11]];
|
||||
|
||||
// restore column 3
|
||||
tmp[12] = XtimeE[state[12]] ^ XtimeB[state[13]] ^ XtimeD[state[14]] ^ Xtime9[state[15]];
|
||||
tmp[1] = Xtime9[state[12]] ^ XtimeE[state[13]] ^ XtimeB[state[14]] ^ XtimeD[state[15]];
|
||||
tmp[6] = XtimeD[state[12]] ^ Xtime9[state[13]] ^ XtimeE[state[14]] ^ XtimeB[state[15]];
|
||||
tmp[11] = XtimeB[state[12]] ^ XtimeD[state[13]] ^ Xtime9[state[14]] ^ XtimeE[state[15]];
|
||||
|
||||
for( i=0; i < 4 * Nb; i++ )
|
||||
state[i] = InvSbox[tmp[i]];
|
||||
}
|
||||
|
||||
// encrypt/decrypt columns of the key
|
||||
// n.b. you can replace this with
|
||||
// byte-wise xor if you wish.
|
||||
|
||||
static void AddRoundKey (unsigned *state, unsigned *key)
|
||||
{
|
||||
int idx;
|
||||
|
||||
for( idx = 0; idx < 4; idx++ )
|
||||
state[idx] ^= key[idx];
|
||||
}
|
||||
|
||||
static const uchar Rcon[11] = {
|
||||
0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
|
||||
|
||||
class CEncryption
|
||||
{
|
||||
public:
|
||||
// produce Nb bytes for each round
|
||||
static void SetEncryptionKey(uchar* key)
|
||||
{
|
||||
uchar* expkey = &expKey[0];
|
||||
uchar tmp0, tmp1, tmp2, tmp3, tmp4;
|
||||
unsigned idx;
|
||||
|
||||
memcpy (expkey, key, Nk * 4);
|
||||
|
||||
for( idx = Nk; idx < Nb * (Nr + 1); idx++ ) {
|
||||
tmp0 = expkey[4*idx - 4];
|
||||
tmp1 = expkey[4*idx - 3];
|
||||
tmp2 = expkey[4*idx - 2];
|
||||
tmp3 = expkey[4*idx - 1];
|
||||
if( !(idx % Nk) ) {
|
||||
tmp4 = tmp3;
|
||||
tmp3 = Sbox[tmp0];
|
||||
tmp0 = Sbox[tmp1] ^ Rcon[idx/Nk];
|
||||
tmp1 = Sbox[tmp2];
|
||||
tmp2 = Sbox[tmp4];
|
||||
} else if( Nk > 6 && idx % Nk == 4 ) {
|
||||
tmp0 = Sbox[tmp0];
|
||||
tmp1 = Sbox[tmp1];
|
||||
tmp2 = Sbox[tmp2];
|
||||
tmp3 = Sbox[tmp3];
|
||||
}
|
||||
|
||||
expkey[4*idx+0] = expkey[4*idx - 4*Nk + 0] ^ tmp0;
|
||||
expkey[4*idx+1] = expkey[4*idx - 4*Nk + 1] ^ tmp1;
|
||||
expkey[4*idx+2] = expkey[4*idx - 4*Nk + 2] ^ tmp2;
|
||||
expkey[4*idx+3] = expkey[4*idx - 4*Nk + 3] ^ tmp3;
|
||||
}
|
||||
}
|
||||
|
||||
// encrypt one 128 bit block
|
||||
static void Encrypt(uchar* in, uchar* out)
|
||||
{
|
||||
uchar* expkey = &expKey[0];
|
||||
uchar state[Nb * 4];
|
||||
unsigned round;
|
||||
|
||||
memcpy (state, in, Nb * 4);
|
||||
AddRoundKey ((unsigned *)state, (unsigned *)expkey);
|
||||
|
||||
for( round = 1; round < Nr + 1; round++ ) {
|
||||
if( round < Nr )
|
||||
MixSubColumns (state);
|
||||
else
|
||||
ShiftRows (state);
|
||||
|
||||
AddRoundKey ((unsigned *)state, (unsigned *)expkey + round * Nb);
|
||||
}
|
||||
|
||||
memcpy (out, state, sizeof(state));
|
||||
}
|
||||
|
||||
static void Decrypt(uchar* in, uchar* out)
|
||||
{
|
||||
uchar* expkey = &expKey[0];
|
||||
uchar state[Nb * 4];
|
||||
unsigned round;
|
||||
|
||||
memcpy (state, in, sizeof(state));
|
||||
|
||||
AddRoundKey ((unsigned *)state, (unsigned *)expkey + Nr * Nb);
|
||||
InvShiftRows(state);
|
||||
|
||||
for( round = Nr; round--; )
|
||||
{
|
||||
AddRoundKey ((unsigned *)state, (unsigned *)expkey + round * Nb);
|
||||
if( round )
|
||||
InvMixSubColumns (state);
|
||||
}
|
||||
|
||||
memcpy (out, state, sizeof(state));
|
||||
}
|
||||
|
||||
private:
|
||||
static uchar expKey[4 * Nb * (Nr + 1)];
|
||||
};
|
|
@ -0,0 +1,120 @@
|
|||
#ifndef IRRNET_CNM_H
|
||||
#define IRRNET_CNM_H
|
||||
|
||||
#include <wchar.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "INetManager.h"
|
||||
#include "SPacket.h"
|
||||
#include "enet/enet.h"
|
||||
|
||||
using namespace irr;
|
||||
using namespace core;
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace net
|
||||
{
|
||||
|
||||
class CNetManager : public INetManager
|
||||
{
|
||||
public:
|
||||
/// This constructor sets up a server, as it only takes a port as a parameter to bind the host to.
|
||||
CNetManager(INetCallback* handler, u32 const port = 45000, const SNetParams& params = SNetParams());
|
||||
|
||||
/// This constructor sets up a client, as it takes an address and a port to connect to. Connecting
|
||||
/// will commence immediately after the INetManager is initialised.
|
||||
CNetManager(INetCallback* handler, const c8* addressc, const u32 port = 45000, const SNetParams& params = SNetParams());
|
||||
|
||||
/// Destructor
|
||||
~CNetManager();
|
||||
|
||||
virtual void update(const u32 timeOut = 0);
|
||||
virtual void setVerbose(bool isverbose);
|
||||
virtual void setNetIterations(u16 iterations) {netIterations = iterations;}
|
||||
virtual void setNetCallback(INetCallback* netCallback) {pHandler = netCallback;}
|
||||
virtual void setGlobalPacketRelay(bool relay);
|
||||
virtual void sendOutPacket(SOutPacket& outpacket);
|
||||
virtual void sendOutPacket(SOutPacket& outpacket, const u16 playerId);
|
||||
virtual void sendOutPacketUnreliable(SOutPacket& outpacket);
|
||||
virtual void sendOutPacketUnreliable(SOutPacket& outpacket, const u16 playerId);
|
||||
virtual void kickClient(const u16 playerId, bool hardKick);
|
||||
|
||||
virtual const u32 getPeerCount();
|
||||
virtual const u32 getPing();
|
||||
virtual const u32 getClientAddress(const u16 playerId);
|
||||
|
||||
virtual const u16 getPlayerNumber();
|
||||
|
||||
virtual E_IRRNET_CONNECTION_STATUS getConnectionStatus();
|
||||
|
||||
enum E_NET_MODE
|
||||
{
|
||||
ENM_SERVER,
|
||||
ENM_CLIENT,
|
||||
|
||||
ENM_COUNT
|
||||
};
|
||||
|
||||
struct SPeerData
|
||||
{
|
||||
SPeerData(u16 pID, ENetPeer* enetPeerIn) : playerID(pID), enetPeer(enetPeerIn) {};
|
||||
|
||||
u16 playerID;
|
||||
ENetPeer* enetPeer;
|
||||
};
|
||||
|
||||
private:
|
||||
ENetHost* host;
|
||||
ENetPeer* peer;
|
||||
ENetAddress address;
|
||||
|
||||
u16 playerID;
|
||||
|
||||
INetCallback* pHandler;
|
||||
u32 netIterations;
|
||||
SNetParams netParams;
|
||||
|
||||
std::vector<SPeerData*> players;
|
||||
bool verbose;
|
||||
bool globPacketRelay;
|
||||
|
||||
E_IRRNET_CONNECTION_STATUS connectionStatus;
|
||||
E_NET_MODE mode;
|
||||
|
||||
bool setUpClient(const c8* addressc, u32 port);
|
||||
bool setUpServer(u32 port);
|
||||
|
||||
ENetPeer* getPlayerById(u16 id);
|
||||
ENetPeer* getPeer();
|
||||
ENetHost* getHost();
|
||||
};
|
||||
|
||||
} // Close Net Namespace
|
||||
} // Close Irr namespace
|
||||
|
||||
#endif
|
||||
|
||||
// Copyright(C) Ahmed Hilali 2007
|
||||
|
||||
/* License:
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgement in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be clearly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
*/
|
|
@ -0,0 +1,242 @@
|
|||
#ifndef IRRNET_INM_H
|
||||
#define IRRNET_INM_H
|
||||
|
||||
#include "SPacket.h"
|
||||
|
||||
/** \mainpage
|
||||
|
||||
Welcome to irrNetLite.
|
||||
|
||||
*/
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace net
|
||||
{
|
||||
|
||||
/**
|
||||
E_IRRNET_CONNECTION_STATUS:
|
||||
|
||||
EICS_PENDING
|
||||
------------
|
||||
The connection is still in progress.
|
||||
|
||||
EICS_ESTABLISHED
|
||||
------------
|
||||
The connection has been successfully established.
|
||||
|
||||
EICS_FAILED
|
||||
------------
|
||||
The connection has failed. The current INetManager is invalid. To retry, you must create a new NetManager.
|
||||
*/
|
||||
enum E_IRRNET_CONNECTION_STATUS
|
||||
{
|
||||
EICS_PENDING,
|
||||
EICS_ESTABLISHED,
|
||||
EICS_FAILED,
|
||||
|
||||
EICS_COUNT
|
||||
};
|
||||
|
||||
/**
|
||||
Optional settings for the creation of the INetManager.
|
||||
|
||||
downBandwidth
|
||||
-------------
|
||||
The down (incoming) bandwidth of the current internet connection. You may set this value for
|
||||
more accurate packet throttling. In kbps.
|
||||
|
||||
upBandwidth
|
||||
-----------
|
||||
The up (outgoing) bandwidth of the current internet connection. You may set this value for
|
||||
more accurate packet throttling. In kbps.
|
||||
|
||||
maxClients
|
||||
----------
|
||||
The maximum number of clients allowed for a server. Any clients that attempt to join
|
||||
after this number has been reached will be rejected. (For servers only.)
|
||||
|
||||
connectionTimeout
|
||||
-----------------
|
||||
The maximum connection timeout allowed when connecting to a server. In milliseconds. (For
|
||||
clients only.)
|
||||
*/
|
||||
struct SNetParams
|
||||
{
|
||||
SNetParams() : downBandwidth(128000), upBandwidth(56000), maxClients(100), connectionTimeout(5000) {};
|
||||
|
||||
u32 downBandwidth;
|
||||
u32 upBandwidth;
|
||||
u32 maxClients;
|
||||
u32 connectionTimeout;
|
||||
};
|
||||
|
||||
/**
|
||||
You must create a derived class of INetCallback and override the "handlePacket" method to perform
|
||||
your own packet handling functions. Everytime a packet is recieved over the network, an SInPacket
|
||||
is passed to this method. When initialising a INetManager, a pointer to an instance of the
|
||||
derived class must be passed. Please see SInPacket regarding information on handling InPackets.
|
||||
*/
|
||||
class INetCallback
|
||||
{
|
||||
public:
|
||||
virtual void handlePacket(SInPacket& packet) = 0;
|
||||
virtual void onConnect(const u16 playerId) {};
|
||||
virtual void onDisconnect(const u16 playerId) {};
|
||||
|
||||
virtual ~INetCallback() {};
|
||||
};
|
||||
|
||||
/**
|
||||
INetManager class.
|
||||
*/
|
||||
class INetManager
|
||||
{
|
||||
public:
|
||||
/**
|
||||
This function updates the state of the NetManager and handles the sending/receiving of packets.
|
||||
Make sure to stick this in your run loop, or at the very least update it very often. If this
|
||||
function is not updated pending packets will not be sent and received packets will not be handled.
|
||||
Optionally a timeout may be specified if you want this function to block and wait for packets
|
||||
to a arrive for a specified interval of time (In MilliSeconds).
|
||||
*/
|
||||
virtual void update(const u32 timeOut = 0) = 0;
|
||||
|
||||
/// Virtual destructor
|
||||
virtual ~INetManager() {};
|
||||
|
||||
/**
|
||||
If set to true INetManager will output debug info to console. Output resembles:
|
||||
|
||||
"irrNetLite: A packet of length 50 was recieved.";
|
||||
|
||||
or
|
||||
|
||||
"irrNetLite: Player number 23 disconnected.";
|
||||
|
||||
It may be useful for debugging purposes.
|
||||
*/
|
||||
virtual void setVerbose(bool isverbose) = 0;
|
||||
|
||||
/// Sets a new INetCallback as the net callback.
|
||||
virtual void setNetCallback(INetCallback* netCallback) = 0;
|
||||
|
||||
/**
|
||||
This function sends an SOutPacket. Out packets provide an easy interface for sending data across a network.
|
||||
Conversions etc are all taken care of by irrNet. All you have to do is create some kind of variable then add it,
|
||||
then read the data from the SInPacket on the recieving end. Here is an example of adding data to an SOutPacket:
|
||||
|
||||
\code
|
||||
SOutPacket MyOutPacket;
|
||||
// We add data using the "<<" operator, similar to iostreams.
|
||||
float myValue = 0.238723f;
|
||||
MyOutPacket << myValue;
|
||||
MyOutPacket << vector3df(23,354,35);
|
||||
MyOutPacket << 43988434;
|
||||
|
||||
// And now to send.
|
||||
NetManager->sendOutPacket(MyOutPacket);
|
||||
\endcode
|
||||
|
||||
This sends the packet to all connected clients if you are the server, or directly to the server if you
|
||||
are a client. To send to a specific client use "sendOutPacket(SOutPacket& outpacket, const u16 playerId)".
|
||||
Please refer to SOutPacket for more information on what types of variables an SOutPacket can handle
|
||||
automatically.
|
||||
*/
|
||||
virtual void sendOutPacket(SOutPacket& outpacket) = 0;
|
||||
|
||||
/**
|
||||
This sends an SOutPacket to a specific player denoted by the player number. Players are numbered
|
||||
automatically as they connect to the server. IMPORTANT: This feature is only valid if you are the server.
|
||||
This is because clients can only send packets to the server, making this function unusable.
|
||||
Please refer to sendOutPacket(const SOutPacket& outpacket) for more info.
|
||||
*/
|
||||
virtual void sendOutPacket(SOutPacket& outpacket, const u16 playerId) = 0;
|
||||
|
||||
/**
|
||||
This sends the SOutPacket specified unreliably. This is not recommended for critical information.
|
||||
Please refer to sendOutPacket(const SOutPacket& outpacket) for more info.
|
||||
*/
|
||||
virtual void sendOutPacketUnreliable(SOutPacket& outpacket) = 0;
|
||||
|
||||
/**
|
||||
This sends an SOutPacket unreliably to a specific player denoted by the player number.
|
||||
Players are numbered automatically as they connect to the server. IMPORTANT: This feature
|
||||
is only valid if you are the server. This is because clients can only send packets to the server,
|
||||
making this function unusable. This is not recommended for critical information.
|
||||
Please refer to sendOutPacket(const SOutPacket& outpacket) for more info.
|
||||
*/
|
||||
virtual void sendOutPacketUnreliable(SOutPacket& outpacket, const u16 playerId) = 0;
|
||||
|
||||
/// This gets the number of players connected. This is only valid for servers.
|
||||
virtual const u32 getPeerCount() = 0;
|
||||
|
||||
/// This returns the playerID for this machine. Only valid for Clients.
|
||||
virtual const u16 getPlayerNumber() = 0;
|
||||
|
||||
/// Returns the client ip address with the specified player ID. This is only valid for servers.
|
||||
/// The address is in 32-bit integer format.
|
||||
virtual const u32 getClientAddress(const u16 playerId) = 0;
|
||||
|
||||
/// Kicks the client with the specified player Id.
|
||||
/// You may set the hardKick option to true to forcifully disconnect them immediately.
|
||||
/// Note that if a "hardKick" is performed, no disconnect event will be generated.
|
||||
virtual void kickClient(const u16 playerId, bool hardKick = false) = 0;
|
||||
|
||||
/**
|
||||
This returns a value of type E_IRRNET_CONNECTION_STATUS. This can either be EICS_PENDING, which indicates the
|
||||
connection is still in process, EICS_ESTABLISHED, which indicates the connection has been successfully established,
|
||||
or EICS_FAILED, which indicates the connection was not successful or has since disconnected. This is generally only
|
||||
useful for clients, but the information is provided for servers incase there is a fault with the server setup.
|
||||
*/
|
||||
virtual E_IRRNET_CONNECTION_STATUS getConnectionStatus() = 0;
|
||||
|
||||
/// This returns the ping. Useful for clients as it returns the ping to the server. For servers it returns
|
||||
/// the ping to the first connected player.
|
||||
virtual const u32 getPing() = 0;
|
||||
|
||||
/// Sets the number of packet processing iterations per update. You may want to increase this number if
|
||||
/// you are not updating frequently enough for all the packets to get processed. (Default: 10000)
|
||||
virtual void setNetIterations(u16 iterations) = 0;
|
||||
|
||||
/**
|
||||
Enables or disables global packet relay, this is when the server relays all the packets it recieves to all
|
||||
connected clients, this makes it easy to send information to all clients, but may not be suitable for
|
||||
large-scale applications. Instead, a custom entity management and packet handling system should be designed.
|
||||
Although for applications with less than 10 peers global packet relay should do just fine. (Default: false)
|
||||
*/
|
||||
virtual void setGlobalPacketRelay(bool relay) = 0;
|
||||
};
|
||||
|
||||
/// Creates an irrNetLite client.
|
||||
INetManager* createIrrNetClient(INetCallback* callback, const c8* addressc, const u32 port = 45000, const SNetParams& params = SNetParams());
|
||||
|
||||
/// Creates an irrNetLite server.
|
||||
INetManager* createIrrNetServer(INetCallback* callback, const u32 port = 45000, const SNetParams& params = SNetParams());
|
||||
|
||||
} // Close Net Namespace
|
||||
} // Close Irr namespace
|
||||
|
||||
#endif
|
||||
|
||||
// Copyright(C) Ahmed Hilali 2008
|
||||
|
||||
/*
|
||||
License:
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgement in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be clearly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
|
@ -0,0 +1,351 @@
|
|||
// Copyright (C) 2002-2007 Nikolaus Gebhardt
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
#ifndef __IRR_COMPILE_CONFIG_H_INCLUDED__
|
||||
#define __IRR_COMPILE_CONFIG_H_INCLUDED__
|
||||
|
||||
//! Irrlicht SDK Version
|
||||
#define IRRLICHT_SDK_VERSION "1.4"
|
||||
|
||||
//! The defines for different operating system are:
|
||||
//! _IRR_XBOX_PLATFORM_ for XBox
|
||||
//! _IRR_WINDOWS_ for all irrlicht supported Windows versions
|
||||
//! _IRR_WINDOWS_API_ for Windows or XBox
|
||||
//! _IRR_LINUX_PLATFORM_ for Linux (it is defined here if no other os is defined)
|
||||
//! _IRR_SOLARIS_PLATFORM_ for Solaris
|
||||
//! _IRR_OSX_PLATFORM_ for Apple systems running OSX
|
||||
//! _IRR_POSIX_API_ for Posix compatible systems
|
||||
//! _IRR_USE_SDL_DEVICE_ for platform independent SDL framework
|
||||
//! _IRR_USE_WINDOWS_DEVICE_ for Windows API based device
|
||||
//! _IRR_USE_WINDOWS_CE_DEVICE_ for Windows CE API based device
|
||||
//! _IRR_USE_LINUX_DEVICE_ for X11 based device
|
||||
//! _IRR_USE_OSX_DEVICE_ for Cocoa native windowing on OSX
|
||||
//! Note: PLATFORM defines the OS specific layer, API can groups several platforms
|
||||
//! DEVICE is the windowing system used, several PLATFORMs support more than one DEVICE
|
||||
//! Moreover, the DEVICE defined here is not directly related to the Irrlicht devices created in the app (but may depend on each other).
|
||||
|
||||
//#define _IRR_USE_SDL_DEVICE_ 1
|
||||
|
||||
//! WIN32 for Windows32
|
||||
//! WIN64 for Windows64
|
||||
// The windows platform and API support SDL and WINDOW device
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(WIN32) || defined(WIN64) || defined(_WIN32_WCE)
|
||||
#define _IRR_WINDOWS_
|
||||
#define _IRR_WINDOWS_API_
|
||||
#ifndef _IRR_USE_SDL_DEVICE_
|
||||
#define _IRR_USE_WINDOWS_DEVICE_
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// XBox only suppots the native Window stuff
|
||||
#if defined(_XBOX)
|
||||
#define _IRR_XBOX_PLATFORM_
|
||||
#define _IRR_WINDOWS_API_
|
||||
#define _IRR_USE_WINDOWS_DEVICE_
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) || defined(MACOSX)
|
||||
#if !defined(MACOSX)
|
||||
#define MACOSX // legacy support
|
||||
#endif
|
||||
#define _IRR_OSX_PLATFORM_
|
||||
#if !defined(_IRR_USE_LINUX_DEVICE_) // for X11 windowing declare this
|
||||
#define _IRR_USE_OSX_DEVICE_
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(_IRR_WINDOWS_API_) && !defined(_IRR_OSX_PLATFORM_)
|
||||
#if defined(__sparc__) || defined(__sun__)
|
||||
#define __BIG_ENDIAN__
|
||||
#define _IRR_SOLARIS_PLATFORM_
|
||||
#else
|
||||
#define _IRR_LINUX_PLATFORM_
|
||||
#endif
|
||||
#define _IRR_POSIX_API_
|
||||
|
||||
#ifndef _IRR_USE_SDL_DEVICE_
|
||||
#define _IRR_USE_LINUX_DEVICE_
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h> // TODO: Although included elsewhere this is required at least for mingw
|
||||
|
||||
//! Define _IRR_COMPILE_WITH_DIRECT3D_8_ and _IRR_COMPILE_WITH_DIRECT3D_9_ to
|
||||
//! compile the Irrlicht engine with Direct3D8 and/or DIRECT3D9.
|
||||
/** If you only want to use the software device or opengl this can be useful.
|
||||
This switch is mostly disabled because people do not get the g++ compiler compile
|
||||
directX header files, and directX is only available on windows platforms. If you
|
||||
are using Dev-Cpp, and want to compile this using a DX dev pack, you can define
|
||||
_IRR_COMPILE_WITH_DX9_DEV_PACK_. So you simply need to add something like this
|
||||
to the compiler settings: -DIRR_COMPILE_WITH_DX9_DEV_PACK
|
||||
and this to the linker settings: -ld3dx9 -ld3dx8 **/
|
||||
#if defined(_IRR_WINDOWS_API_) && (!defined(__GNUC__) || defined(IRR_COMPILE_WITH_DX9_DEV_PACK))
|
||||
|
||||
//#define _IRR_COMPILE_WITH_DIRECT3D_8_
|
||||
//#define _IRR_COMPILE_WITH_DIRECT3D_9_
|
||||
|
||||
#endif
|
||||
|
||||
#define _IRR_COMPILE_WITH_BLINDRT_
|
||||
|
||||
//! Define _IRR_COMPILE_WITH_OPENGL_ to compile the Irrlicht engine with OpenGL.
|
||||
/** If you do not wish the engine to be compiled with OpengGL, comment this
|
||||
define out. */
|
||||
//#define _IRR_COMPILE_WITH_OPENGL_
|
||||
|
||||
//! Define _IRR_COMPILE_WITH_SOFTWARE_ to compile the Irrlicht engine with software driver
|
||||
/** If you do not need the software driver, or want to use Burning's Video instead,
|
||||
comment this define out */
|
||||
//#define _IRR_COMPILE_WITH_SOFTWARE_
|
||||
|
||||
//! Define _IRR_COMPILE_WITH_BURNINGSVIDEO_ to compile the Irrlicht engine with Burning's video driver
|
||||
/** If you do not need this software driver, you can comment this define out. */
|
||||
#define _IRR_COMPILE_WITH_BURNINGSVIDEO_
|
||||
|
||||
//! Define _IRR_COMPILE_WITH_X11_ to compile the Irrlicht engine with X11 support.
|
||||
/** If you do not wish the engine to be compiled with X11, comment this
|
||||
define out. */
|
||||
// Only used in LinuxDevice.
|
||||
#define _IRR_COMPILE_WITH_X11_
|
||||
|
||||
//! Define _IRR_OPENGL_USE_EXTPOINTER_ if the OpenGL renderer should use OpenGL extensions via function pointers.
|
||||
/** On some systems there is no support for the dynamic extension of OpenGL
|
||||
via function pointers such that this has to be undef'ed. */
|
||||
#if !defined(_IRR_OSX_PLATFORM_) && !defined(_IRR_SOLARIS_PLATFORM_)
|
||||
#define _IRR_OPENGL_USE_EXTPOINTER_
|
||||
#endif
|
||||
|
||||
//! On some Linux systems the XF86 vidmode extension or X11 RandR are missing. Use these flags
|
||||
//! to remove the dependencies such that Irrlicht will compile on those systems, too.
|
||||
#if defined(_IRR_LINUX_PLATFORM_)
|
||||
#define _IRR_LINUX_X11_VIDMODE_
|
||||
//#define _IRR_LINUX_X11_RANDR_
|
||||
#endif
|
||||
|
||||
//! Define _IRR_COMPILE_WITH_GUI_ to compile the engine with the built-in GUI
|
||||
/** Disable this if you are using an external library to draw the GUI. If you disable this then
|
||||
you will not be able to use anything provided by the GUI Environment, including loading fonts. */
|
||||
#define _IRR_COMPILE_WITH_GUI_
|
||||
|
||||
//! Define _IRR_COMPILE_WITH_ZLIB_ to enable compiling the engine using zlib.
|
||||
/** This enables the engine to read from compressed .zip archives. If you
|
||||
disable this feature, the engine can still read archives, but only uncompressed
|
||||
ones. */
|
||||
#define _IRR_COMPILE_WITH_ZLIB_
|
||||
|
||||
//! Define _IRR_USE_NON_SYSTEM_ZLIB_ to let irrlicht use the zlib which comes with irrlicht.
|
||||
/** If this is commented out, Irrlicht will try to compile using the zlib installed in the system.
|
||||
This is only used when _IRR_COMPILE_WITH_ZLIB_ is defined. */
|
||||
#define _IRR_USE_NON_SYSTEM_ZLIB_
|
||||
|
||||
|
||||
//! Define _IRR_COMPILE_WITH_JPEGLIB_ to enable compiling the engine using libjpeg.
|
||||
/** This enables the engine to read jpeg images. If you comment this out,
|
||||
the engine will no longer read .jpeg images. */
|
||||
#define _IRR_COMPILE_WITH_LIBJPEG_
|
||||
|
||||
//! Define _IRR_USE_NON_SYSTEM_JPEG_LIB_ to let irrlicht use the jpeglib which comes with irrlicht.
|
||||
/** If this is commented out, Irrlicht will try to compile using the jpeg lib installed in the system.
|
||||
This is only used when _IRR_COMPILE_WITH_LIBJPEG_ is defined. */
|
||||
#define _IRR_USE_NON_SYSTEM_JPEG_LIB_
|
||||
|
||||
|
||||
//! Define _IRR_COMPILE_WITH_LIBPNG_ to enable compiling the engine using libpng.
|
||||
/** This enables the engine to read png images. If you comment this out,
|
||||
the engine will no longer read .png images. */
|
||||
#define _IRR_COMPILE_WITH_LIBPNG_
|
||||
|
||||
//! Define _IRR_USE_NON_SYSTEM_LIBPNG_ to let irrlicht use the libpng which comes with irrlicht.
|
||||
/** If this is commented out, Irrlicht will try to compile using the libpng installed in the system.
|
||||
This is only used when _IRR_COMPILE_WITH_LIBPNG_ is defined. */
|
||||
#define _IRR_USE_NON_SYSTEM_LIB_PNG_
|
||||
|
||||
|
||||
//! Define _IRR_D3D_NO_SHADER_DEBUGGING to disable shader debugging in D3D9
|
||||
/** If _IRR_D3D_NO_SHADER_DEBUGGING is undefined in IrrCompileConfig.h,
|
||||
it is possible to debug all D3D9 shaders in VisualStudio. All shaders
|
||||
(which have been generated in memory or read from archives for example) will be emitted
|
||||
into a temporary file at runtime for this purpose. To debug your shaders, choose
|
||||
Debug->Direct3D->StartWithDirect3DDebugging in Visual Studio, and for every shader a
|
||||
file named 'irr_dbg_shader_%%.vsh' or 'irr_dbg_shader_%%.psh' will be created. Drag'n'drop
|
||||
the file you want to debug into visual studio. That's it. You can now set breakpoints and
|
||||
watch registers, variables etc. This works with ASM, HLSL, and both with pixel and vertex shaders.
|
||||
Note that the engine will run in D3D REF for this, which is a lot slower than HAL. */
|
||||
#define _IRR_D3D_NO_SHADER_DEBUGGING
|
||||
|
||||
|
||||
#ifdef _IRR_WINDOWS_API_
|
||||
|
||||
#ifndef _IRR_STATIC_LIB_
|
||||
#ifdef IRRLICHT_EXPORTS
|
||||
#define IRRLICHT_API __declspec(dllexport)
|
||||
#else
|
||||
#define IRRLICHT_API __declspec(dllimport)
|
||||
#endif // IRRLICHT_EXPORT
|
||||
#else
|
||||
#define IRRLICHT_API
|
||||
#endif // _IRR_STATIC_LIB_
|
||||
|
||||
// Declare the calling convention.
|
||||
#if defined(_STDCALL_SUPPORTED)
|
||||
#define IRRCALLCONV __stdcall
|
||||
#else
|
||||
#define IRRCALLCONV __cdecl
|
||||
#endif // STDCALL_SUPPORTED
|
||||
|
||||
#else
|
||||
#define IRRLICHT_API
|
||||
#define IRRCALLCONV
|
||||
#endif // _IRR_WINDOWS_API_
|
||||
|
||||
// We need to disable DIRECT3D9 support for Visual Studio 6.0 because
|
||||
// those $%&$!! disabled support for it since Dec. 2004 and users are complaining
|
||||
// about linker errors. Comment this out only if you are knowing what you are
|
||||
// doing. (Which means you have an old DX9 SDK and VisualStudio6).
|
||||
#ifdef _MSC_VER
|
||||
#if (_MSC_VER < 1300 && !defined(__GNUC__))
|
||||
#undef _IRR_COMPILE_WITH_DIRECT3D_9_
|
||||
#pragma message("Compiling Irrlicht with Visual Studio 6.0, support for DX9 is disabled.")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//! Define one of the three setting for Burning's Video Software Rasterizer
|
||||
/** So if we were marketing guys we could say Irrlicht has 4 Software-Rasterizers.
|
||||
In a Nutshell:
|
||||
All Burnings Rasterizers use 32 Bit Backbuffer, 32Bit Texture & 32 Bit Z or WBuffer,
|
||||
16 Bit/32 Bit can be adjusted on a global flag.
|
||||
|
||||
BURNINGVIDEO_RENDERER_BEAUTIFUL
|
||||
32 Bit + Vertexcolor + Lighting + Per Pixel Perspective Correct + SubPixel/SubTexel Correct +
|
||||
Bilinear Texturefiltering + WBuffer
|
||||
|
||||
BURNINGVIDEO_RENDERER_FAST
|
||||
32 Bit + Per Pixel Perspective Correct + SubPixel/SubTexel Correct + WBuffer +
|
||||
Bilinear Dithering TextureFiltering + WBuffer
|
||||
|
||||
BURNINGVIDEO_RENDERER_ULTRA_FAST
|
||||
16Bit + SubPixel/SubTexel Correct + ZBuffer
|
||||
*/
|
||||
|
||||
#define BURNINGVIDEO_RENDERER_BEAUTIFUL
|
||||
//#define BURNINGVIDEO_RENDERER_FAST
|
||||
//#define BURNINGVIDEO_RENDERER_ULTRA_FAST
|
||||
|
||||
|
||||
//! Define _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ if you want to use bone based
|
||||
/** animated meshes. If you compile without this, you will be unable to load
|
||||
B3D, MS3D or X meshes */
|
||||
#define _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_
|
||||
|
||||
#ifdef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_
|
||||
//! Define _IRR_COMPILE_WITH_B3D_LOADER_ if you want to use Blitz3D files
|
||||
#define _IRR_COMPILE_WITH_B3D_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_B3D_LOADER_ if you want to Milkshape files
|
||||
#define _IRR_COMPILE_WITH_MS3D_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_X_LOADER_ if you want to use Microsoft X files
|
||||
#define _IRR_COMPILE_WITH_X_LOADER_
|
||||
#endif
|
||||
|
||||
//! Define _IRR_COMPILE_WITH_IRR_MESH_LOADER_ if you want to load Irrlicht Engine .irrmesh files
|
||||
#define _IRR_COMPILE_WITH_IRR_MESH_LOADER_
|
||||
|
||||
//! Define _IRR_COMPILE_WITH_MD2_LOADER_ if you want to load Quake 2 animated files
|
||||
#define _IRR_COMPILE_WITH_MD2_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_MD3_LOADER_ if you want to load Quake 3 animated files
|
||||
#define _IRR_COMPILE_WITH_MD3_LOADER_
|
||||
|
||||
//! Define _IRR_COMPILE_WITH_3DS_LOADER_ if you want to load 3D Studio Max files
|
||||
#define _IRR_COMPILE_WITH_3DS_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_COLLADA_LOADER_ if you want to load Collada files
|
||||
#define _IRR_COMPILE_WITH_COLLADA_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_CSM_LOADER_ if you want to load Cartography Shop files
|
||||
#define _IRR_COMPILE_WITH_CSM_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_BSP_LOADER_ if you want to load Quake 3 BSP files
|
||||
#define _IRR_COMPILE_WITH_BSP_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_DMF_LOADER_ if you want to load DeleD files
|
||||
#define _IRR_COMPILE_WITH_DMF_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_LMTS_LOADER_ if you want to load LMTools files
|
||||
#define _IRR_COMPILE_WITH_LMTS_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_MY3D_LOADER_ if you want to load MY3D files
|
||||
#define _IRR_COMPILE_WITH_MY3D_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_OBJ_LOADER_ if you want to load Wavefront OBJ files
|
||||
#define _IRR_COMPILE_WITH_OBJ_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_OCT_LOADER_ if you want to load FSRad OCT files
|
||||
#define _IRR_COMPILE_WITH_OCT_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_OGRE_LOADER_ if you want to load Ogre 3D files
|
||||
#define _IRR_COMPILE_WITH_OGRE_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_LWO_LOADER_ if you want to load Lightwave3D files
|
||||
#define _IRR_COMPILE_WITH_LWO_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_STL_LOADER_ if you want to load .stl files
|
||||
#define _IRR_COMPILE_WITH_STL_LOADER_
|
||||
|
||||
//! Define _IRR_COMPILE_WITH_IRR_WRITER_ if you want to write static .irr files
|
||||
#define _IRR_COMPILE_WITH_IRR_WRITER_
|
||||
//! Define _IRR_COMPILE_WITH_COLLADA_WRITER_ if you want to write Collada files
|
||||
#define _IRR_COMPILE_WITH_COLLADA_WRITER_
|
||||
//! Define _IRR_COMPILE_WITH_STL_WRITER_ if you want to write .stl files
|
||||
#define _IRR_COMPILE_WITH_STL_WRITER_
|
||||
|
||||
//! Define _IRR_COMPILE_WITH_BMP_LOADER_ if you want to load .bmp files
|
||||
//! Disabling this loader will also disable the built-in font
|
||||
#define _IRR_COMPILE_WITH_BMP_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_JPG_LOADER_ if you want to load .jpg files
|
||||
#define _IRR_COMPILE_WITH_JPG_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_PCX_LOADER_ if you want to load .pcx files
|
||||
#define _IRR_COMPILE_WITH_PCX_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_PNG_LOADER_ if you want to load .png files
|
||||
#define _IRR_COMPILE_WITH_PNG_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_PPM_LOADER_ if you want to load .ppm/.pgm/.pbm files
|
||||
#define _IRR_COMPILE_WITH_PPM_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_PSD_LOADER_ if you want to load .psd files
|
||||
#define _IRR_COMPILE_WITH_PSD_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_TGA_LOADER_ if you want to load .tga files
|
||||
#define _IRR_COMPILE_WITH_TGA_LOADER_
|
||||
//! Define _IRR_COMPILE_WITH_WAL_LOADER_ if you want to load .wal files
|
||||
#define _IRR_COMPILE_WITH_WAL_LOADER_
|
||||
|
||||
//! Define _IRR_COMPILE_WITH_BMP_WRITER_ if you want to write .bmp files
|
||||
#define _IRR_COMPILE_WITH_BMP_WRITER_
|
||||
//! Define _IRR_COMPILE_WITH_JPG_WRITER_ if you want to write .jpg files
|
||||
#define _IRR_COMPILE_WITH_JPG_WRITER_
|
||||
//! Define _IRR_COMPILE_WITH_PCX_WRITER_ if you want to write .pcx files
|
||||
#define _IRR_COMPILE_WITH_PCX_WRITER_
|
||||
//! Define _IRR_COMPILE_WITH_PNG_WRITER_ if you want to write .png files
|
||||
#define _IRR_COMPILE_WITH_PNG_WRITER_
|
||||
//! Define _IRR_COMPILE_WITH_PPM_WRITER_ if you want to write .ppm files
|
||||
#define _IRR_COMPILE_WITH_PPM_WRITER_
|
||||
//! Define _IRR_COMPILE_WITH_PSD_WRITER_ if you want to write .psd files
|
||||
#define _IRR_COMPILE_WITH_PSD_WRITER_
|
||||
//! Define _IRR_COMPILE_WITH_TGA_WRITER_ if you want to write .tga files
|
||||
#define _IRR_COMPILE_WITH_TGA_WRITER_
|
||||
|
||||
//! Set FPU settings
|
||||
/** Irrlicht should use approximate float and integer fpu techniques
|
||||
precision will be lower but speed higher. currently X86 only
|
||||
*/
|
||||
#if !defined(_IRR_OSX_PLATFORM_) && !defined(_IRR_SOLARIS_PLATFORM_)
|
||||
//#define IRRLICHT_FAST_MATH
|
||||
#endif
|
||||
|
||||
// Some cleanup
|
||||
// XBox does not have OpenGL or DirectX9
|
||||
#if defined(_IRR_XBOX_PLATFORM_)
|
||||
#undef _IRR_COMPILE_WITH_OPENGL_
|
||||
#undef _IRR_COMPILE_WITH_DIRECT3D_9_
|
||||
#endif
|
||||
|
||||
// WinCE does not have OpenGL or DirectX9
|
||||
#if defined(_WIN32_WCE)
|
||||
#undef _IRR_COMPILE_WITH_OPENGL_
|
||||
#undef _IRR_COMPILE_WITH_DIRECT3D_8_
|
||||
#undef _IRR_COMPILE_WITH_DIRECT3D_9_
|
||||
#undef _IRR_COMPILE_WITH_SOFTWARE_
|
||||
#undef BURNINGVIDEO_RENDERER_BEAUTIFUL
|
||||
#undef _IRR_USE_WINDOWS_DEVICE_
|
||||
#define _IRR_USE_WINDOWS_CE_DEVICE_
|
||||
#define BURNINGVIDEO_RENDERER_CE
|
||||
#endif
|
||||
|
||||
#endif // __IRR_COMPILE_CONFIG_H_INCLUDED__
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef IRRNET_INO_IRRLICHT_H
|
||||
#define IRRNET_INO_IRRLICHT_H
|
||||
|
||||
#include "irrTypes.h"
|
||||
#include "irrArray.h"
|
||||
#include "irrString.h"
|
||||
#include "vector3d.h"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright (C) 2002-2007 Nikolaus Gebhardt
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
#ifndef __IRR_HEAPSORT_H_INCLUDED__
|
||||
#define __IRR_HEAPSORT_H_INCLUDED__
|
||||
|
||||
#include "irrTypes.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
//! Sinks an element into the heap.
|
||||
template<class T>
|
||||
inline void heapsink(T*array, s32 element, s32 max)
|
||||
{
|
||||
while ((element<<1) < max) // there is a left child
|
||||
{
|
||||
s32 j = (element<<1);
|
||||
|
||||
if (j+1 < max && array[j] < array[j+1])
|
||||
j = j+1; // take right child
|
||||
|
||||
if (array[element] < array[j])
|
||||
{
|
||||
T t = array[j]; // swap elements
|
||||
array[j] = array[element];
|
||||
array[element] = t;
|
||||
element = j;
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! Sorts an array with size 'size' using heapsort.
|
||||
template<class T>
|
||||
inline void heapsort(T* array_, s32 size)
|
||||
{
|
||||
// for heapsink we pretent this is not c++, where
|
||||
// arrays start with index 0. So we decrease the array pointer,
|
||||
// the maximum always +2 and the element always +1
|
||||
|
||||
T* virtualArray = array_ - 1;
|
||||
s32 virtualSize = size + 2;
|
||||
s32 i;
|
||||
|
||||
// build heap
|
||||
|
||||
for (i=((size-1)/2); i>=0; --i)
|
||||
heapsink(virtualArray, i+1, virtualSize-1);
|
||||
|
||||
// sort array
|
||||
|
||||
for (i=size-1; i>=0; --i)
|
||||
{
|
||||
T t = array_[0];
|
||||
array_[0] = array_[i];
|
||||
array_[i] = t;
|
||||
heapsink(virtualArray, 1, i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace core
|
||||
} // end namespace irr
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
// Copyright (C) 2002-2007 Nikolaus Gebhardt
|
||||
// This file is part of the "Irrlicht Engine" and the "irrXML" project.
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
|
||||
|
||||
#ifndef __IRR_ALLOCATOR_H_INCLUDED__
|
||||
#define __IRR_ALLOCATOR_H_INCLUDED__
|
||||
|
||||
#include "irrTypes.h"
|
||||
#include <new>
|
||||
#include <memory.h>
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
#ifdef DEBUG_CLIENTBLOCK
|
||||
#undef DEBUG_CLIENTBLOCK
|
||||
#define DEBUG_CLIENTBLOCK new
|
||||
#endif
|
||||
|
||||
//! Very simple allocator implementation, containers using it can
|
||||
//! be used across dll boundaries
|
||||
template<typename T>
|
||||
class irrAllocator
|
||||
{
|
||||
public:
|
||||
|
||||
//! destructor
|
||||
virtual ~irrAllocator() {}
|
||||
|
||||
//! allocate memory for an array of objects
|
||||
T* allocate(size_t cnt)
|
||||
{
|
||||
return (T*)internal_new(cnt* sizeof(T));
|
||||
}
|
||||
|
||||
//! deallocate memory for an array of objects
|
||||
void deallocate(T* ptr)
|
||||
{
|
||||
internal_delete(ptr);
|
||||
}
|
||||
|
||||
//! construct an element
|
||||
void construct(T* ptr, const T&e)
|
||||
{
|
||||
new ((void*)ptr) T(e);
|
||||
}
|
||||
|
||||
//! destruct an element
|
||||
void destruct(T* ptr)
|
||||
{
|
||||
ptr->~T();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
virtual void* internal_new(size_t cnt)
|
||||
{
|
||||
return operator new(cnt);
|
||||
}
|
||||
|
||||
virtual void internal_delete(void* ptr)
|
||||
{
|
||||
operator delete(ptr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
//! fast allocator, only to be used in containers inside the same memory heap.
|
||||
/** Containers using it are NOT able to be used it across dll boundaries. Use this
|
||||
when using in an internal class or function or when compiled into a static lib */
|
||||
template<typename T>
|
||||
class irrAllocatorFast
|
||||
{
|
||||
public:
|
||||
|
||||
//! allocate memory for an array of objects
|
||||
T* allocate(size_t cnt)
|
||||
{
|
||||
return (T*)operator new(cnt* sizeof(T));
|
||||
}
|
||||
|
||||
//! deallocate memory for an array of objects
|
||||
void deallocate(T* ptr)
|
||||
{
|
||||
operator delete(ptr);
|
||||
}
|
||||
|
||||
//! construct an element
|
||||
void construct(T* ptr, const T&e)
|
||||
{
|
||||
new ((void*)ptr) T(e);
|
||||
}
|
||||
|
||||
//! destruct an element
|
||||
void destruct(T* ptr)
|
||||
{
|
||||
ptr->~T();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG_CLIENTBLOCK
|
||||
#undef DEBUG_CLIENTBLOCK
|
||||
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
|
||||
#endif
|
||||
|
||||
|
||||
} // end namespace core
|
||||
} // end namespace irr
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,515 @@
|
|||
// Copyright (C) 2002-2007 Nikolaus Gebhardt
|
||||
// This file is part of the "Irrlicht Engine" and the "irrXML" project.
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
|
||||
|
||||
#ifndef __IRR_ARRAY_H_INCLUDED__
|
||||
#define __IRR_ARRAY_H_INCLUDED__
|
||||
|
||||
#include "irrTypes.h"
|
||||
#include "heapsort.h"
|
||||
#include "irrAllocator.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
//! Self reallocating template array (like stl vector) with additional features.
|
||||
/** Some features are: Heap sorting, binary search methods, easier debugging.
|
||||
*/
|
||||
template <class T, typename TAlloc = irrAllocator<T> >
|
||||
class array
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
array()
|
||||
: data(0), allocated(0), used(0),
|
||||
free_when_destroyed(true), is_sorted(true)
|
||||
{
|
||||
}
|
||||
|
||||
//! Constructs a array and allocates an initial chunk of memory.
|
||||
//! \param start_count: Amount of elements to allocate.
|
||||
array(u32 start_count)
|
||||
: data(0), allocated(0), used(0),
|
||||
free_when_destroyed(true), is_sorted(true)
|
||||
{
|
||||
reallocate(start_count);
|
||||
}
|
||||
|
||||
|
||||
//! Copy constructor
|
||||
array(const array<T>& other)
|
||||
: data(0)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Destructor. Frees allocated memory, if set_free_when_destroyed
|
||||
//! was not set to false by the user before.
|
||||
~array()
|
||||
{
|
||||
if (free_when_destroyed)
|
||||
{
|
||||
for (u32 i=0; i<used; ++i)
|
||||
allocator.destruct(&data[i]);
|
||||
|
||||
allocator.deallocate(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Reallocates the array, make it bigger or smaller.
|
||||
//! \param new_size: New size of array.
|
||||
void reallocate(u32 new_size)
|
||||
{
|
||||
T* old_data = data;
|
||||
|
||||
data = allocator.allocate(new_size); //new T[new_size];
|
||||
allocated = new_size;
|
||||
|
||||
// copy old data
|
||||
s32 end = used < new_size ? used : new_size;
|
||||
|
||||
for (s32 i=0; i<end; ++i)
|
||||
{
|
||||
// data[i] = old_data[i];
|
||||
allocator.construct(&data[i], old_data[i]);
|
||||
}
|
||||
|
||||
// destruct old data
|
||||
for (u32 j=0; j<used; ++j)
|
||||
allocator.destruct(&old_data[j]);
|
||||
|
||||
if (allocated < used)
|
||||
used = allocated;
|
||||
|
||||
allocator.deallocate(old_data); //delete [] old_data;
|
||||
}
|
||||
|
||||
//! Adds an element at back of array. If the array is too small to
|
||||
//! add this new element it is made bigger.
|
||||
//! \param element: Element to add at the back of the array.
|
||||
void push_back(const T& element)
|
||||
{
|
||||
if (used + 1 > allocated)
|
||||
{
|
||||
// reallocate(used * 2 +1);
|
||||
// this doesn't work if the element is in the same array. So
|
||||
// we'll copy the element first to be sure we'll get no data
|
||||
// corruption
|
||||
|
||||
T e(element);
|
||||
reallocate(used * 2 +1); // increase data block
|
||||
|
||||
allocator.construct(&data[used++], e); // data[used++] = e; // push_back
|
||||
}
|
||||
else
|
||||
{
|
||||
//data[used++] = element;
|
||||
// instead of using this here, we copy it the safe way:
|
||||
allocator.construct(&data[used++], element);
|
||||
}
|
||||
|
||||
is_sorted = false;
|
||||
}
|
||||
|
||||
|
||||
//! Adds an element at the front of the array. If the array is to small to
|
||||
//! add this new element, the array is made bigger. Please note that this
|
||||
//! is slow, because the whole array needs to be copied for this.
|
||||
//! \param element: Element to add at the back of the array.
|
||||
void push_front(const T& element)
|
||||
{
|
||||
insert(element);
|
||||
}
|
||||
|
||||
|
||||
//! Insert item into array at specified position. Please use this
|
||||
//! only if you know what you are doing (possible performance loss).
|
||||
//! The preferred method of adding elements should be push_back().
|
||||
//! \param element: Element to be inserted
|
||||
//! \param index: Where position to insert the new element.
|
||||
void insert(const T& element, u32 index=0)
|
||||
{
|
||||
_IRR_DEBUG_BREAK_IF(index>used) // access violation
|
||||
|
||||
if (used + 1 > allocated)
|
||||
reallocate(used +1);
|
||||
|
||||
for (u32 i=used; i>index; --i)
|
||||
{
|
||||
if (i<used)
|
||||
allocator.destruct(&data[i]);
|
||||
allocator.construct(&data[i], data[i-1]); // data[i] = data[i-1];
|
||||
}
|
||||
|
||||
if (used > index)
|
||||
allocator.destruct(&data[index]);
|
||||
allocator.construct(&data[index], element); // data[index] = element;
|
||||
is_sorted = false;
|
||||
++used;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//! Clears the array and deletes all allocated memory.
|
||||
void clear()
|
||||
{
|
||||
for (u32 i=0; i<used; ++i)
|
||||
allocator.destruct(&data[i]);
|
||||
|
||||
allocator.deallocate(data); // delete [] data;
|
||||
data = 0;
|
||||
used = 0;
|
||||
allocated = 0;
|
||||
is_sorted = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Sets pointer to new array, using this as new workspace.
|
||||
//! \param newPointer: Pointer to new array of elements.
|
||||
//! \param size: Size of the new array.
|
||||
void set_pointer(T* newPointer, u32 size)
|
||||
{
|
||||
for (u32 i=0; i<used; ++i)
|
||||
allocator.destruct(&data[i]);
|
||||
|
||||
allocator.deallocate(data); // delete [] data;
|
||||
data = newPointer;
|
||||
allocated = size;
|
||||
used = size;
|
||||
is_sorted = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Sets if the array should delete the memory it used.
|
||||
//! \param f: If true, the array frees the allocated memory in its
|
||||
//! destructor, otherwise not. The default is true.
|
||||
void set_free_when_destroyed(bool f)
|
||||
{
|
||||
free_when_destroyed = f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Sets the size of the array and adds some new elements if necessary.
|
||||
/** Please note: This is only secure when using it with simple types, because
|
||||
no default constructor will be called for the added new elements.
|
||||
\param usedNow: Amount of elements now used. */
|
||||
void set_used(u32 usedNow)
|
||||
{
|
||||
if (allocated < usedNow)
|
||||
reallocate(usedNow);
|
||||
|
||||
used = usedNow;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Assignment operator
|
||||
void operator=(const array<T>& other)
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
for (u32 i=0; i<used; ++i)
|
||||
allocator.destruct(&data[i]);
|
||||
|
||||
allocator.deallocate(data); // delete [] data;
|
||||
}
|
||||
|
||||
//if (allocated < other.allocated)
|
||||
if (other.allocated == 0)
|
||||
data = 0;
|
||||
else
|
||||
data = allocator.allocate(other.allocated); // new T[other.allocated];
|
||||
|
||||
used = other.used;
|
||||
free_when_destroyed = other.free_when_destroyed;
|
||||
is_sorted = other.is_sorted;
|
||||
allocated = other.allocated;
|
||||
|
||||
for (u32 i=0; i<other.used; ++i)
|
||||
allocator.construct(&data[i], other.data[i]); // data[i] = other.data[i];
|
||||
}
|
||||
|
||||
// equality operator
|
||||
bool operator == (const array<T>& other) const
|
||||
{
|
||||
if (used != other.used)
|
||||
return false;
|
||||
|
||||
for (u32 i=0; i<other.used; ++i)
|
||||
if (data[i] != other[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// inequality operator
|
||||
bool operator != (const array<T>& other) const
|
||||
{
|
||||
return !(*this==other);
|
||||
}
|
||||
|
||||
//! Direct access operator
|
||||
T& operator [](u32 index)
|
||||
{
|
||||
_IRR_DEBUG_BREAK_IF(index>=used) // access violation
|
||||
|
||||
return data[index];
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Direct access operator
|
||||
const T& operator [](u32 index) const
|
||||
{
|
||||
_IRR_DEBUG_BREAK_IF(index>=used) // access violation
|
||||
|
||||
return data[index];
|
||||
}
|
||||
|
||||
//! Gets last frame
|
||||
T& getLast()
|
||||
{
|
||||
_IRR_DEBUG_BREAK_IF(!used) // access violation
|
||||
|
||||
return data[used-1];
|
||||
}
|
||||
|
||||
|
||||
//! Gets last frame
|
||||
const T& getLast() const
|
||||
{
|
||||
_IRR_DEBUG_BREAK_IF(!used) // access violation
|
||||
|
||||
return data[used-1];
|
||||
}
|
||||
|
||||
//! Returns a pointer to the array.
|
||||
//! \return Pointer to the array.
|
||||
T* pointer()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Returns a const pointer to the array.
|
||||
//! \return Pointer to the array.
|
||||
const T* const_pointer() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Returns size of used array.
|
||||
//! \return Size of elements in the array.
|
||||
u32 size() const
|
||||
{
|
||||
return used;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Returns amount memory allocated.
|
||||
//! \return Returns amount of memory allocated. The amount of bytes
|
||||
//! allocated would be allocated_size() * sizeof(ElementsUsed);
|
||||
u32 allocated_size() const
|
||||
{
|
||||
return allocated;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Returns true if array is empty
|
||||
//! \return True if the array is empty, false if not.
|
||||
bool empty() const
|
||||
{
|
||||
return used == 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Sorts the array using heapsort. There is no additional memory waste and
|
||||
//! the algorithm performs O(n*log n) in worst case.
|
||||
void sort()
|
||||
{
|
||||
if (is_sorted || used<2)
|
||||
return;
|
||||
|
||||
heapsort(data, used);
|
||||
is_sorted = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Performs a binary search for an element, returns -1 if not found.
|
||||
//! The array will be sorted before the binary search if it is not
|
||||
//! already sorted.
|
||||
//! \param element: Element to search for.
|
||||
//! \return Returns position of the searched element if it was found,
|
||||
//! otherwise -1 is returned.
|
||||
s32 binary_search(const T& element)
|
||||
{
|
||||
sort();
|
||||
return binary_search(element, 0, used-1);
|
||||
}
|
||||
|
||||
//! Performs a binary search for an element, returns -1 if not found.
|
||||
//! The array must be sorted prior
|
||||
//! \param element: Element to search for.
|
||||
//! \return Returns position of the searched element if it was found,
|
||||
//! otherwise -1 is returned.
|
||||
s32 binary_search_const(const T& element) const
|
||||
{
|
||||
return binary_search(element, 0, used-1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Performs a binary search for an element, returns -1 if not found.
|
||||
//! \param element: Element to search for.
|
||||
//! \param left: First left index
|
||||
//! \param right: Last right index.
|
||||
//! \return Returns position of the searched element if it was found,
|
||||
//! otherwise -1 is returned.
|
||||
s32 binary_search(const T& element, s32 left, s32 right) const
|
||||
{
|
||||
if (!used)
|
||||
return -1;
|
||||
|
||||
s32 m;
|
||||
|
||||
do
|
||||
{
|
||||
m = (left+right)>>1;
|
||||
|
||||
if (element < data[m])
|
||||
right = m - 1;
|
||||
else
|
||||
left = m + 1;
|
||||
|
||||
} while((element < data[m] || data[m] < element) && left<=right);
|
||||
// this last line equals to:
|
||||
// " while((element != array[m]) && left<=right);"
|
||||
// but we only want to use the '<' operator.
|
||||
// the same in next line, it is "(element == array[m])"
|
||||
|
||||
|
||||
if (!(element < data[m]) && !(data[m] < element))
|
||||
return m;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//! Finds an element in linear time, which is very slow. Use
|
||||
//! binary_search for faster finding. Only works if ==operator is implemented.
|
||||
//! \param element: Element to search for.
|
||||
//! \return Returns position of the searched element if it was found,
|
||||
//! otherwise -1 is returned.
|
||||
s32 linear_search(const T& element) const
|
||||
{
|
||||
for (u32 i=0; i<used; ++i)
|
||||
if (element == data[i])
|
||||
return (s32)i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//! Finds an element in linear time, which is very slow. Use
|
||||
//! binary_search for faster finding. Only works if ==operator is implemented.
|
||||
//! \param element: Element to search for.
|
||||
//! \return Returns position of the searched element if it was found,
|
||||
//! otherwise -1 is returned.
|
||||
s32 linear_reverse_search(const T& element) const
|
||||
{
|
||||
for (s32 i=used-1; i>=0; --i)
|
||||
if (data[i] == element)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Erases an element from the array. May be slow, because all elements
|
||||
//! following after the erased element have to be copied.
|
||||
//! \param index: Index of element to be erased.
|
||||
void erase(u32 index)
|
||||
{
|
||||
_IRR_DEBUG_BREAK_IF(index>=used) // access violation
|
||||
|
||||
for (u32 i=index+1; i<used; ++i)
|
||||
{
|
||||
allocator.destruct(&data[i-1]);
|
||||
allocator.construct(&data[i-1], data[i]); // data[i-1] = data[i];
|
||||
}
|
||||
|
||||
allocator.destruct(&data[used-1]);
|
||||
|
||||
--used;
|
||||
}
|
||||
|
||||
|
||||
//! Erases some elements from the array. may be slow, because all elements
|
||||
//! following after the erased element have to be copied.
|
||||
//! \param index: Index of the first element to be erased.
|
||||
//! \param count: Amount of elements to be erased.
|
||||
void erase(u32 index, s32 count)
|
||||
{
|
||||
_IRR_DEBUG_BREAK_IF(index>=used || count<1 || index+count>used) // access violation
|
||||
|
||||
u32 i;
|
||||
for (i=index; i<index+count; ++i)
|
||||
allocator.destruct(&data[i]);
|
||||
|
||||
for (i=index+count; i<used; ++i)
|
||||
{
|
||||
if (i > index+count)
|
||||
allocator.destruct(&data[i-count]);
|
||||
|
||||
allocator.construct(&data[i-count], data[i]); // data[i-count] = data[i];
|
||||
|
||||
if (i >= used-count)
|
||||
allocator.destruct(&data[i]);
|
||||
}
|
||||
|
||||
used-= count;
|
||||
}
|
||||
|
||||
|
||||
//! Sets if the array is sorted
|
||||
void set_sorted(bool _is_sorted)
|
||||
{
|
||||
is_sorted = _is_sorted;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
T* data;
|
||||
u32 allocated;
|
||||
u32 used;
|
||||
bool free_when_destroyed;
|
||||
bool is_sorted;
|
||||
TAlloc allocator;
|
||||
};
|
||||
|
||||
|
||||
} // end namespace core
|
||||
} // end namespace irr
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,456 @@
|
|||
// Copyright (C) 2002-2007 Nikolaus Gebhardt
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
#ifndef __IRR_MATH_H_INCLUDED__
|
||||
#define __IRR_MATH_H_INCLUDED__
|
||||
|
||||
#include "IrrCompileConfig.h"
|
||||
#include "irrTypes.h"
|
||||
#include <math.h>
|
||||
|
||||
#if defined(_IRR_SOLARIS_PLATFORM_) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) || defined (_WIN32_WCE)
|
||||
#define sqrtf(X) (f32)sqrt((f64)(X))
|
||||
#define sinf(X) (f32)sin((f64)(X))
|
||||
#define cosf(X) (f32)cos((f64)(X))
|
||||
#define asinf(X) (f32)asin((f64)(X))
|
||||
#define acosf(X) (f32)acos((f64)(X))
|
||||
#define atan2f(X,Y) (f32)atan2((f64)(X),(f64)(Y))
|
||||
#define ceilf(X) (f32)ceil((f64)(X))
|
||||
#define floorf(X) (f32)floor((f64)(X))
|
||||
#define powf(X,Y) (f32)pow((f64)(X),(f64)(Y))
|
||||
#define fmodf(X,Y) (f32)fmod((f64)(X),(f64)(Y))
|
||||
#define fabsf(X) (f32)fabs((f64)(X))
|
||||
#endif
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
//! Rounding error constant often used when comparing f32 values.
|
||||
|
||||
#ifdef IRRLICHT_FAST_MATH
|
||||
const f32 ROUNDING_ERROR_32 = 0.00005f;
|
||||
const f64 ROUNDING_ERROR_64 = 0.000005f;
|
||||
#else
|
||||
const f32 ROUNDING_ERROR_32 = 0.000001f;
|
||||
const f64 ROUNDING_ERROR_64 = 0.00000001f;
|
||||
#endif
|
||||
|
||||
#ifdef PI // make sure we don't collide with a define
|
||||
#undef PI
|
||||
#endif
|
||||
//! Constant for PI.
|
||||
const f32 PI = 3.14159265359f;
|
||||
|
||||
//! Constant for reciprocal of PI.
|
||||
const f32 RECIPROCAL_PI = 1.0f/PI;
|
||||
|
||||
//! Constant for half of PI.
|
||||
const f32 HALF_PI = PI/2.0f;
|
||||
|
||||
#ifdef PI64 // make sure we don't collide with a define
|
||||
#undef PI64
|
||||
#endif
|
||||
//! Constant for 64bit PI.
|
||||
const f64 PI64 = 3.1415926535897932384626433832795028841971693993751;
|
||||
|
||||
//! Constant for 64bit reciprocal of PI.
|
||||
const f64 RECIPROCAL_PI64 = 1.0/PI64;
|
||||
|
||||
//! 32bit Constant for converting from degrees to radians
|
||||
const f32 DEGTORAD = PI / 180.0f;
|
||||
|
||||
//! 32bit constant for converting from radians to degrees (formally known as GRAD_PI)
|
||||
const f32 RADTODEG = 180.0f / PI;
|
||||
|
||||
//! 64bit constant for converting from degrees to radians (formally known as GRAD_PI2)
|
||||
const f64 DEGTORAD64 = PI64 / 180.0;
|
||||
|
||||
//! 64bit constant for converting from radians to degrees
|
||||
const f64 RADTODEG64 = 180.0 / PI64;
|
||||
|
||||
//! returns minimum of two values. Own implementation to get rid of the STL (VS6 problems)
|
||||
template<class T>
|
||||
inline const T& min_(const T& a, const T& b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
//! returns minimum of three values. Own implementation to get rid of the STL (VS6 problems)
|
||||
template<class T>
|
||||
inline const T& min_(const T& a, const T& b, const T& c)
|
||||
{
|
||||
return a < b ? min_(a, c) : min_(b, c);
|
||||
}
|
||||
|
||||
//! returns maximum of two values. Own implementation to get rid of the STL (VS6 problems)
|
||||
template<class T>
|
||||
inline const T& max_(const T& a, const T& b)
|
||||
{
|
||||
return a < b ? b : a;
|
||||
}
|
||||
|
||||
//! returns maximum of three values. Own implementation to get rid of the STL (VS6 problems)
|
||||
template<class T>
|
||||
inline const T& max_(const T& a, const T& b, const T& c)
|
||||
{
|
||||
return a < b ? max_(b, c) : max_(a, c);
|
||||
}
|
||||
|
||||
//! returns abs of two values. Own implementation to get rid of STL (VS6 problems)
|
||||
template<class T>
|
||||
inline T abs_(const T& a)
|
||||
{
|
||||
return a < (T)0 ? -a : a;
|
||||
}
|
||||
|
||||
//! returns linear interpolation of a and b with ratio t
|
||||
//! \return: a if t==0, b if t==1, and the linear interpolation else
|
||||
template<class T>
|
||||
inline T lerp(const T& a, const T& b, const f32 t)
|
||||
{
|
||||
return (T)(a*(1.f-t)) + (b*t);
|
||||
}
|
||||
|
||||
//! clamps a value between low and high
|
||||
template <class T>
|
||||
inline const T clamp (const T& value, const T& low, const T& high)
|
||||
{
|
||||
return min_ (max_(value,low), high);
|
||||
}
|
||||
|
||||
//! returns if a equals b, taking possible rounding errors into account
|
||||
inline bool equals(const f32 a, const f32 b, const f32 tolerance = ROUNDING_ERROR_32)
|
||||
{
|
||||
return (a + tolerance >= b) && (a - tolerance <= b);
|
||||
}
|
||||
|
||||
//! returns if a equals b, taking possible rounding errors into account
|
||||
inline bool equals(const s32 a, const s32 b, const s32 tolerance = 0)
|
||||
{
|
||||
return (a + tolerance >= b) && (a - tolerance <= b);
|
||||
}
|
||||
|
||||
//! returns if a equals b, taking possible rounding errors into account
|
||||
inline bool equals(const u32 a, const u32 b, const u32 tolerance = 0)
|
||||
{
|
||||
return (a + tolerance >= b) && (a - tolerance <= b);
|
||||
}
|
||||
|
||||
//! returns if a equals zero, taking rounding errors into account
|
||||
inline bool iszero(const f32 a, const f32 tolerance = ROUNDING_ERROR_32)
|
||||
{
|
||||
return fabsf ( a ) <= tolerance;
|
||||
}
|
||||
|
||||
//! returns if a equals zero, taking rounding errors into account
|
||||
inline bool iszero(const s32 a, const s32 tolerance = 0)
|
||||
{
|
||||
return ( a & 0x7ffffff ) <= tolerance;
|
||||
}
|
||||
|
||||
//! returns if a equals zero, taking rounding errors into account
|
||||
inline bool iszero(const u32 a, const u32 tolerance = 0)
|
||||
{
|
||||
return a <= tolerance;
|
||||
}
|
||||
|
||||
inline s32 s32_min ( s32 a, s32 b)
|
||||
{
|
||||
s32 mask = (a - b) >> 31;
|
||||
return (a & mask) | (b & ~mask);
|
||||
}
|
||||
|
||||
inline s32 s32_max ( s32 a, s32 b)
|
||||
{
|
||||
s32 mask = (a - b) >> 31;
|
||||
return (b & mask) | (a & ~mask);
|
||||
}
|
||||
|
||||
inline s32 s32_clamp (s32 value, s32 low, s32 high)
|
||||
{
|
||||
return s32_min (s32_max(value,low), high);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
float IEEE-754 bit represenation
|
||||
|
||||
0 0x00000000
|
||||
1.0 0x3f800000
|
||||
0.5 0x3f000000
|
||||
3 0x40400000
|
||||
+inf 0x7f800000
|
||||
-inf 0xff800000
|
||||
+NaN 0x7fc00000 or 0x7ff00000
|
||||
in general: number = (sign ? -1:1) * 2^(exponent) * 1.(mantissa bits)
|
||||
*/
|
||||
|
||||
#define F32_AS_S32(f) (*((s32 *) &(f)))
|
||||
#define F32_AS_U32(f) (*((u32 *) &(f)))
|
||||
#define F32_AS_U32_POINTER(f) ( ((u32 *) &(f)))
|
||||
|
||||
#define F32_VALUE_0 0x00000000
|
||||
#define F32_VALUE_1 0x3f800000
|
||||
#define F32_SIGN_BIT 0x80000000U
|
||||
#define F32_EXPON_MANTISSA 0x7FFFFFFFU
|
||||
|
||||
//! code is taken from IceFPU
|
||||
//! Integer representation of a floating-point value.
|
||||
#define IR(x) ((u32&)(x))
|
||||
|
||||
//! Absolute integer representation of a floating-point value
|
||||
#define AIR(x) (IR(x)&0x7fffffff)
|
||||
|
||||
//! Floating-point representation of an integer value.
|
||||
#define FR(x) ((f32&)(x))
|
||||
|
||||
#define IEEE_1_0 0x3f800000 //!< integer representation of 1.0
|
||||
#define IEEE_255_0 0x437f0000 //!< integer representation of 255.0
|
||||
|
||||
#ifdef IRRLICHT_FAST_MATH
|
||||
#define F32_LOWER_0(f) (F32_AS_U32(f) > F32_SIGN_BIT)
|
||||
#define F32_LOWER_EQUAL_0(f) (F32_AS_S32(f) <= F32_VALUE_0)
|
||||
#define F32_GREATER_0(f) (F32_AS_S32(f) > F32_VALUE_0)
|
||||
#define F32_GREATER_EQUAL_0(f) (F32_AS_U32(f) <= F32_SIGN_BIT)
|
||||
#define F32_EQUAL_1(f) (F32_AS_U32(f) == F32_VALUE_1)
|
||||
#define F32_EQUAL_0(f) ( (F32_AS_U32(f) & F32_EXPON_MANTISSA ) == F32_VALUE_0)
|
||||
|
||||
// only same sign
|
||||
#define F32_A_GREATER_B(a,b) (F32_AS_S32((a)) > F32_AS_S32((b)))
|
||||
|
||||
#else
|
||||
|
||||
#define F32_LOWER_0(n) ((n) < 0.0f)
|
||||
#define F32_LOWER_EQUAL_0(n) ((n) <= 0.0f)
|
||||
#define F32_GREATER_0(n) ((n) > 0.0f)
|
||||
#define F32_GREATER_EQUAL_0(n) ((n) >= 0.0f)
|
||||
#define F32_EQUAL_1(n) ((n) == 1.0f)
|
||||
#define F32_EQUAL_0(n) ((n) == 0.0f)
|
||||
#define F32_A_GREATER_B(a,b) ((a) > (b))
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef REALINLINE
|
||||
#ifdef _MSC_VER
|
||||
#define REALINLINE __forceinline
|
||||
#else
|
||||
#define REALINLINE inline
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
//! conditional set based on mask and arithmetic shift
|
||||
REALINLINE u32 if_c_a_else_b ( const s32 condition, const u32 a, const u32 b )
|
||||
{
|
||||
return ( ( -condition >> 31 ) & ( a ^ b ) ) ^ b;
|
||||
}
|
||||
|
||||
//! conditional set based on mask and arithmetic shift
|
||||
REALINLINE u32 if_c_a_else_0 ( const s32 condition, const u32 a )
|
||||
{
|
||||
return ( -condition >> 31 ) & a;
|
||||
}
|
||||
|
||||
/*
|
||||
if (condition) state |= m; else state &= ~m;
|
||||
*/
|
||||
REALINLINE void setbit_cond ( u32 &state, s32 condition, u32 mask )
|
||||
{
|
||||
// 0, or any postive to mask
|
||||
//s32 conmask = -condition >> 31;
|
||||
state ^= ( ( -condition >> 31 ) ^ state ) & mask;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline f32 round_( f32 x )
|
||||
{
|
||||
return floorf( x + 0.5f );
|
||||
}
|
||||
|
||||
REALINLINE void clearFPUException ()
|
||||
{
|
||||
#ifdef IRRLICHT_FAST_MATH
|
||||
#ifdef feclearexcept
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
#elif defined(_MSC_VER)
|
||||
__asm fnclex;
|
||||
#elif defined(__GNUC__) && defined(__x86__)
|
||||
__asm__ __volatile__ ("fclex \n\t");
|
||||
#else
|
||||
# warn clearFPUException not supported.
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
REALINLINE f32 reciprocal_squareroot(const f32 x)
|
||||
{
|
||||
#ifdef IRRLICHT_FAST_MATH
|
||||
// comes from Nvidia
|
||||
#if 1
|
||||
u32 tmp = (u32(IEEE_1_0 << 1) + IEEE_1_0 - *(u32*)&x) >> 1;
|
||||
f32 y = *(f32*)&tmp;
|
||||
return y * (1.47f - 0.47f * x * y * y);
|
||||
#elif defined(_MSC_VER)
|
||||
// an sse2 version
|
||||
__asm
|
||||
{
|
||||
movss xmm0, x
|
||||
rsqrtss xmm0, xmm0
|
||||
movss x, xmm0
|
||||
}
|
||||
return x;
|
||||
#endif
|
||||
#else // no fast math
|
||||
return 1.f / sqrtf ( x );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
REALINLINE f32 reciprocal ( const f32 f )
|
||||
{
|
||||
#ifdef IRRLICHT_FAST_MATH
|
||||
//! i do not divide through 0.. (fpu expection)
|
||||
// instead set f to a high value to get a return value near zero..
|
||||
// -1000000000000.f.. is use minus to stay negative..
|
||||
// must test's here (plane.normal dot anything ) checks on <= 0.f
|
||||
return 1.f / f;
|
||||
//u32 x = (-(AIR(f) != 0 ) >> 31 ) & ( IR(f) ^ 0xd368d4a5 ) ^ 0xd368d4a5;
|
||||
//return 1.f / FR ( x );
|
||||
#else // no fast math
|
||||
return 1.f / f;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
REALINLINE f32 reciprocal_approxim ( const f32 p )
|
||||
{
|
||||
#ifdef IRRLICHT_FAST_MATH
|
||||
register u32 x = 0x7F000000 - IR ( p );
|
||||
const f32 r = FR ( x );
|
||||
return r * (2.0f - p * r);
|
||||
#else // no fast math
|
||||
return 1.f / p;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
REALINLINE s32 floor32(f32 x)
|
||||
{
|
||||
#ifdef IRRLICHT_FAST_MATH
|
||||
const f32 h = 0.5f;
|
||||
|
||||
s32 t;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
__asm
|
||||
{
|
||||
fld x
|
||||
fsub h
|
||||
fistp t
|
||||
}
|
||||
#elif defined(__GNUC__)
|
||||
__asm__ __volatile__ (
|
||||
"fsub %2 \n\t"
|
||||
"fistpl %0"
|
||||
: "=m" (t)
|
||||
: "t" (x), "f" (h)
|
||||
: "st"
|
||||
);
|
||||
#else
|
||||
# warn IRRLICHT_FAST_MATH not supported.
|
||||
return (s32) floorf ( x );
|
||||
#endif
|
||||
return t;
|
||||
#else // no fast math
|
||||
return (s32) floorf ( x );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
REALINLINE s32 ceil32 ( f32 x )
|
||||
{
|
||||
#ifdef IRRLICHT_FAST_MATH
|
||||
const f32 h = 0.5f;
|
||||
|
||||
s32 t;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
__asm
|
||||
{
|
||||
fld x
|
||||
fadd h
|
||||
fistp t
|
||||
}
|
||||
#elif defined(__GNUC__)
|
||||
__asm__ __volatile__ (
|
||||
"fadd %2 \n\t"
|
||||
"fistpl %0 \n\t"
|
||||
: "=m"(t)
|
||||
: "t"(x), "f"(h)
|
||||
: "st"
|
||||
);
|
||||
#else
|
||||
# warn IRRLICHT_FAST_MATH not supported.
|
||||
return (s32) ceilf ( x );
|
||||
#endif
|
||||
return t;
|
||||
#else // not fast math
|
||||
return (s32) ceilf ( x );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
REALINLINE s32 round32(f32 x)
|
||||
{
|
||||
#if defined(IRRLICHT_FAST_MATH)
|
||||
s32 t;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
__asm
|
||||
{
|
||||
fld x
|
||||
fistp t
|
||||
}
|
||||
#elif defined(__GNUC__)
|
||||
__asm__ __volatile__ (
|
||||
"fistpl %0 \n\t"
|
||||
: "=m"(t)
|
||||
: "t"(x)
|
||||
: "st"
|
||||
);
|
||||
#else
|
||||
# warn IRRLICHT_FAST_MATH not supported.
|
||||
return (s32) round_(x);
|
||||
#endif
|
||||
return t;
|
||||
#else // no fast math
|
||||
return (s32) round_(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline f32 f32_max3(const f32 a, const f32 b, const f32 c)
|
||||
{
|
||||
return a > b ? (a > c ? a : c) : (b > c ? b : c);
|
||||
}
|
||||
|
||||
inline f32 f32_min3(const f32 a, const f32 b, const f32 c)
|
||||
{
|
||||
return a < b ? (a < c ? a : c) : (b < c ? b : c);
|
||||
}
|
||||
|
||||
inline f32 fract ( f32 x )
|
||||
{
|
||||
return x - floorf ( x );
|
||||
}
|
||||
|
||||
} // end namespace core
|
||||
} // end namespace irr
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,891 @@
|
|||
// Copyright (C) 2002-2007 Nikolaus Gebhardt
|
||||
// This file is part of the "Irrlicht Engine" and the "irrXML" project.
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
|
||||
|
||||
#ifndef __IRR_STRING_H_INCLUDED__
|
||||
#define __IRR_STRING_H_INCLUDED__
|
||||
|
||||
#include "irrTypes.h"
|
||||
#include "irrAllocator.h"
|
||||
#include "irrMath.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
//! Very simple string class with some useful features.
|
||||
/** string<c8> and string<wchar_t> work both with unicode AND ascii,
|
||||
so you can assign unicode to string<c8> and ascii to string<wchar_t>
|
||||
(and the other way round) if your ever would want to.
|
||||
Note that the conversation between both is not done using an encoding.
|
||||
|
||||
Known bugs:
|
||||
Special characters like umlauts are ignored in the
|
||||
methods make_upper, make_lower and equals_ignore_case.
|
||||
*/
|
||||
template <typename T, typename TAlloc = irrAllocator<T> >
|
||||
class string
|
||||
{
|
||||
public:
|
||||
|
||||
//! Default constructor
|
||||
string()
|
||||
: array(0), allocated(1), used(1)
|
||||
{
|
||||
array = allocator.allocate(1); // new T[1];
|
||||
array[0] = 0x0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Constructor
|
||||
string(const string<T>& other)
|
||||
: array(0), allocated(0), used(0)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Constructs a string from a float
|
||||
string(const double number)
|
||||
: array(0), allocated(0), used(0)
|
||||
{
|
||||
c8 tmpbuf[255];
|
||||
snprintf(tmpbuf, 255, "%0.6f", number);
|
||||
*this = tmpbuf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Constructs a string from an int
|
||||
string(int number)
|
||||
: array(0), allocated(0), used(0)
|
||||
{
|
||||
// store if negative and make positive
|
||||
|
||||
bool negative = false;
|
||||
if (number < 0)
|
||||
{
|
||||
number *= -1;
|
||||
negative = true;
|
||||
}
|
||||
|
||||
// temporary buffer for 16 numbers
|
||||
|
||||
c8 tmpbuf[16];
|
||||
tmpbuf[15] = 0;
|
||||
u32 idx = 15;
|
||||
|
||||
// special case '0'
|
||||
|
||||
if (!number)
|
||||
{
|
||||
tmpbuf[14] = '0';
|
||||
*this = &tmpbuf[14];
|
||||
return;
|
||||
}
|
||||
|
||||
// add numbers
|
||||
|
||||
while(number && idx)
|
||||
{
|
||||
--idx;
|
||||
tmpbuf[idx] = (c8)('0' + (number % 10));
|
||||
number /= 10;
|
||||
}
|
||||
|
||||
// add sign
|
||||
|
||||
if (negative)
|
||||
{
|
||||
--idx;
|
||||
tmpbuf[idx] = '-';
|
||||
}
|
||||
|
||||
*this = &tmpbuf[idx];
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Constructs a string from an unsigned int
|
||||
string(unsigned int number)
|
||||
: array(0), allocated(0), used(0)
|
||||
{
|
||||
// temporary buffer for 16 numbers
|
||||
|
||||
c8 tmpbuf[16];
|
||||
tmpbuf[15] = 0;
|
||||
u32 idx = 15;
|
||||
|
||||
// special case '0'
|
||||
|
||||
if (!number)
|
||||
{
|
||||
tmpbuf[14] = '0';
|
||||
*this = &tmpbuf[14];
|
||||
return;
|
||||
}
|
||||
|
||||
// add numbers
|
||||
|
||||
while(number && idx)
|
||||
{
|
||||
--idx;
|
||||
tmpbuf[idx] = (c8)('0' + (number % 10));
|
||||
number /= 10;
|
||||
}
|
||||
|
||||
*this = &tmpbuf[idx];
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Constructor for copying a string from a pointer with a given length
|
||||
template <class B>
|
||||
string(const B* const c, u32 length)
|
||||
: array(0), allocated(0), used(0)
|
||||
{
|
||||
if (!c)
|
||||
{
|
||||
// correctly init the string to an empty one
|
||||
*this="";
|
||||
return;
|
||||
}
|
||||
|
||||
allocated = used = length+1;
|
||||
array = allocator.allocate(used); // new T[used];
|
||||
|
||||
for (u32 l = 0; l<length; ++l)
|
||||
array[l] = (T)c[l];
|
||||
|
||||
array[length] = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Constructor for unicode and ascii strings
|
||||
template <class B>
|
||||
string(const B* const c)
|
||||
: array(0), allocated(0), used(0)
|
||||
{
|
||||
*this = c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! destructor
|
||||
~string()
|
||||
{
|
||||
allocator.deallocate(array); // delete [] array;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Assignment operator
|
||||
string<T>& operator=(const string<T>& other)
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
allocator.deallocate(array); // delete [] array;
|
||||
allocated = used = other.size()+1;
|
||||
array = allocator.allocate(used); //new T[used];
|
||||
|
||||
const T* p = other.c_str();
|
||||
for (u32 i=0; i<used; ++i, ++p)
|
||||
array[i] = *p;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Assignment operator for strings, ascii and unicode
|
||||
template <class B>
|
||||
string<T>& operator=(const B* const c)
|
||||
{
|
||||
if (!c)
|
||||
{
|
||||
if (!array)
|
||||
{
|
||||
array = allocator.allocate(1); //new T[1];
|
||||
allocated = 1;
|
||||
}
|
||||
used = 1;
|
||||
array[0] = 0x0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
if ((void*)c == (void*)array)
|
||||
return *this;
|
||||
|
||||
u32 len = 0;
|
||||
const B* p = c;
|
||||
while(*p)
|
||||
{
|
||||
++len;
|
||||
++p;
|
||||
}
|
||||
|
||||
// we'll take the old string for a while, because the new
|
||||
// string could be a part of the current string.
|
||||
T* oldArray = array;
|
||||
|
||||
++len;
|
||||
allocated = used = len;
|
||||
array = allocator.allocate(used); //new T[used];
|
||||
|
||||
for (u32 l = 0; l<len; ++l)
|
||||
array[l] = (T)c[l];
|
||||
|
||||
allocator.deallocate(oldArray); // delete [] oldArray;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Add operator for other strings
|
||||
string<T> operator+(const string<T>& other) const
|
||||
{
|
||||
string<T> str(*this);
|
||||
str.append(other);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
//! Add operator for strings, ascii and unicode
|
||||
template <class B>
|
||||
string<T> operator+(const B* const c) const
|
||||
{
|
||||
string<T> str(*this);
|
||||
str.append(c);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
//! Direct access operator
|
||||
T& operator [](const u32 index)
|
||||
{
|
||||
_IRR_DEBUG_BREAK_IF(index>=used) // bad index
|
||||
return array[index];
|
||||
}
|
||||
|
||||
|
||||
//! Direct access operator
|
||||
const T& operator [](const u32 index) const
|
||||
{
|
||||
_IRR_DEBUG_BREAK_IF(index>=used) // bad index
|
||||
return array[index];
|
||||
}
|
||||
|
||||
|
||||
//! Comparison operator
|
||||
bool operator ==(const T* const str) const
|
||||
{
|
||||
if (!str)
|
||||
return false;
|
||||
|
||||
u32 i;
|
||||
for(i=0; array[i] && str[i]; ++i)
|
||||
if (array[i] != str[i])
|
||||
return false;
|
||||
|
||||
return !array[i] && !str[i];
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Comparison operator
|
||||
bool operator ==(const string<T>& other) const
|
||||
{
|
||||
for(u32 i=0; array[i] && other.array[i]; ++i)
|
||||
if (array[i] != other.array[i])
|
||||
return false;
|
||||
|
||||
return used == other.used;
|
||||
}
|
||||
|
||||
|
||||
//! Is smaller operator
|
||||
bool operator <(const string<T>& other) const
|
||||
{
|
||||
for(u32 i=0; array[i] && other.array[i]; ++i)
|
||||
{
|
||||
s32 diff = array[i] - other.array[i];
|
||||
if ( diff )
|
||||
return diff < 0;
|
||||
/*
|
||||
if (array[i] != other.array[i])
|
||||
return (array[i] < other.array[i]);
|
||||
*/
|
||||
}
|
||||
|
||||
return used < other.used;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Equals not operator
|
||||
bool operator !=(const T* const str) const
|
||||
{
|
||||
return !(*this == str);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Equals not operator
|
||||
bool operator !=(const string<T>& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Returns length of string
|
||||
/** \return Returns length of the string in characters. */
|
||||
u32 size() const
|
||||
{
|
||||
return used-1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Returns character string
|
||||
/** \return Returns pointer to C-style zero terminated string. */
|
||||
const T* c_str() const
|
||||
{
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Makes the string lower case.
|
||||
void make_lower()
|
||||
{
|
||||
for (u32 i=0; i<used; ++i)
|
||||
array[i] = ansi_lower ( array[i] );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Makes the string upper case.
|
||||
void make_upper()
|
||||
{
|
||||
const T a = (T)'a';
|
||||
const T z = (T)'z';
|
||||
const T diff = (T)'A' - a;
|
||||
|
||||
for (u32 i=0; i<used; ++i)
|
||||
{
|
||||
if (array[i]>=a && array[i]<=z)
|
||||
array[i] += diff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Compares the string ignoring case.
|
||||
/** \param other: Other string to compare.
|
||||
\return Returns true if the string are equal ignoring case. */
|
||||
bool equals_ignore_case(const string<T>& other) const
|
||||
{
|
||||
for(u32 i=0; array[i] && other[i]; ++i)
|
||||
if (ansi_lower(array[i]) != ansi_lower(other[i]))
|
||||
return false;
|
||||
|
||||
return used == other.used;
|
||||
}
|
||||
|
||||
//! Compares the string ignoring case.
|
||||
/** \param other: Other string to compare.
|
||||
\return Returns true if the string is smaller ignoring case. */
|
||||
bool lower_ignore_case(const string<T>& other) const
|
||||
{
|
||||
for(u32 i=0; array[i] && other.array[i]; ++i)
|
||||
{
|
||||
s32 diff = (s32) ansi_lower ( array[i] ) - (s32) ansi_lower ( other.array[i] );
|
||||
if ( diff )
|
||||
return diff < 0;
|
||||
}
|
||||
|
||||
return used < other.used;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! compares the first n characters of the strings
|
||||
bool equalsn(const string<T>& other, u32 n) const
|
||||
{
|
||||
u32 i;
|
||||
for(i=0; array[i] && other[i] && i < n; ++i)
|
||||
if (array[i] != other[i])
|
||||
return false;
|
||||
|
||||
// if one (or both) of the strings was smaller then they
|
||||
// are only equal if they have the same length
|
||||
return (i == n) || (used == other.used);
|
||||
}
|
||||
|
||||
|
||||
//! compares the first n characters of the strings
|
||||
bool equalsn(const T* const str, u32 n) const
|
||||
{
|
||||
if (!str)
|
||||
return false;
|
||||
s32 i;
|
||||
for(i=0; array[i] && str[i] && i < n; ++i)
|
||||
if (array[i] != str[i])
|
||||
return false;
|
||||
|
||||
// if one (or both) of the strings was smaller then they
|
||||
// are only equal if they have the same length
|
||||
return (i == n) || (array[i] == 0 && str[i] == 0);
|
||||
}
|
||||
|
||||
|
||||
//! Appends a character to this string
|
||||
/** \param character: Character to append. */
|
||||
void append(T character)
|
||||
{
|
||||
if (used + 1 > allocated)
|
||||
reallocate(used + 1);
|
||||
|
||||
++used;
|
||||
|
||||
array[used-2] = character;
|
||||
array[used-1] = 0;
|
||||
}
|
||||
|
||||
//! Appends a char string to this string
|
||||
/** \param other: Char string to append. */
|
||||
void append(const T* const other)
|
||||
{
|
||||
if (!other)
|
||||
return;
|
||||
|
||||
u32 len = 0;
|
||||
const T* p = other;
|
||||
while(*p)
|
||||
{
|
||||
++len;
|
||||
++p;
|
||||
}
|
||||
|
||||
if (used + len > allocated)
|
||||
reallocate(used + len);
|
||||
|
||||
--used;
|
||||
++len;
|
||||
|
||||
for (u32 l=0; l<len; ++l)
|
||||
array[l+used] = *(other+l);
|
||||
|
||||
used += len;
|
||||
}
|
||||
|
||||
|
||||
//! Appends a string to this string
|
||||
/** \param other: String to append. */
|
||||
void append(const string<T>& other)
|
||||
{
|
||||
--used;
|
||||
u32 len = other.size()+1;
|
||||
|
||||
if (used + len > allocated)
|
||||
reallocate(used + len);
|
||||
|
||||
for (u32 l=0; l<len; ++l)
|
||||
array[used+l] = other[l];
|
||||
|
||||
used += len;
|
||||
}
|
||||
|
||||
|
||||
//! Appends a string of the length l to this string.
|
||||
/** \param other: other String to append to this string.
|
||||
\param length: How much characters of the other string to add to this one. */
|
||||
void append(const string<T>& other, u32 length)
|
||||
{
|
||||
if (other.size() < length)
|
||||
{
|
||||
append(other);
|
||||
return;
|
||||
}
|
||||
|
||||
if (used + length > allocated)
|
||||
reallocate(used + length);
|
||||
|
||||
--used;
|
||||
|
||||
for (u32 l=0; l<length; ++l)
|
||||
array[l+used] = other[l];
|
||||
used += length;
|
||||
|
||||
// ensure proper termination
|
||||
array[used]=0;
|
||||
++used;
|
||||
}
|
||||
|
||||
|
||||
//! Reserves some memory.
|
||||
/** \param count: Amount of characters to reserve. */
|
||||
void reserve(u32 count)
|
||||
{
|
||||
if (count < allocated)
|
||||
return;
|
||||
|
||||
reallocate(count);
|
||||
}
|
||||
|
||||
|
||||
//! finds first occurrence of character in string
|
||||
/** \param c: Character to search for.
|
||||
\return Returns position where the character has been found,
|
||||
or -1 if not found. */
|
||||
s32 findFirst(T c) const
|
||||
{
|
||||
for (u32 i=0; i<used; ++i)
|
||||
if (array[i] == c)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//! finds first occurrence of a character of a list in string
|
||||
/** \param c: List of characters to find. For example if the method
|
||||
should find the first occurrence of 'a' or 'b', this parameter should be "ab".
|
||||
\param count: Amount of characters in the list. Usually,
|
||||
this should be strlen(c)
|
||||
\return Returns position where one of the characters has been found,
|
||||
or -1 if not found. */
|
||||
s32 findFirstChar(const T* const c, u32 count) const
|
||||
{
|
||||
if (!c)
|
||||
return -1;
|
||||
|
||||
for (u32 i=0; i<used; ++i)
|
||||
for (u32 j=0; j<count; ++j)
|
||||
if (array[i] == c[j])
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//! Finds first position of a character not in a given list.
|
||||
/** \param c: List of characters not to find. For example if the method
|
||||
should find the first occurrence of a character not 'a' or 'b', this parameter should be "ab".
|
||||
\param count: Amount of characters in the list. Usually,
|
||||
this should be strlen(c)
|
||||
\return Returns position where the character has been found,
|
||||
or -1 if not found. */
|
||||
template <class B>
|
||||
s32 findFirstCharNotInList(const B* const c, u32 count) const
|
||||
{
|
||||
for (u32 i=0; i<used-1; ++i)
|
||||
{
|
||||
u32 j;
|
||||
for (j=0; j<count; ++j)
|
||||
if (array[i] == c[j])
|
||||
break;
|
||||
|
||||
if (j==count)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//! Finds last position of a character not in a given list.
|
||||
/** \param c: List of characters not to find. For example if the method
|
||||
should find the first occurrence of a character not 'a' or 'b', this parameter should be "ab".
|
||||
\param count: Amount of characters in the list. Usually,
|
||||
this should be strlen(c)
|
||||
\return Returns position where the character has been found,
|
||||
or -1 if not found. */
|
||||
template <class B>
|
||||
s32 findLastCharNotInList(const B* const c, u32 count) const
|
||||
{
|
||||
for (s32 i=(s32)(used-2); i>=0; --i)
|
||||
{
|
||||
u32 j;
|
||||
for (j=0; j<count; ++j)
|
||||
if (array[i] == c[j])
|
||||
break;
|
||||
|
||||
if (j==count)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//! finds next occurrence of character in string
|
||||
/** \param c: Character to search for.
|
||||
\param startPos: Position in string to start searching.
|
||||
\return Returns position where the character has been found,
|
||||
or -1 if not found. */
|
||||
s32 findNext(T c, u32 startPos) const
|
||||
{
|
||||
for (u32 i=startPos; i<used; ++i)
|
||||
if (array[i] == c)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//! finds last occurrence of character in string
|
||||
//! \param c: Character to search for.
|
||||
//! \param start: start to search reverse ( default = -1, on end )
|
||||
//! \return Returns position where the character has been found,
|
||||
//! or -1 if not found.
|
||||
s32 findLast(T c, s32 start = -1) const
|
||||
{
|
||||
start = core::clamp ( start < 0 ? (s32)(used) - 1 : start, 0, (s32)(used) - 1 );
|
||||
for (s32 i=start; i>=0; --i)
|
||||
if (array[i] == c)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//! finds last occurrence of a character of a list in string
|
||||
/** \param c: List of strings to find. For example if the method
|
||||
should find the last occurrence of 'a' or 'b', this parameter should be "ab".
|
||||
\param count: Amount of characters in the list. Usually,
|
||||
this should be strlen(c)
|
||||
\return Returns position where one of the characters has been found,
|
||||
or -1 if not found. */
|
||||
s32 findLastChar(const T* const c, u32 count) const
|
||||
{
|
||||
if (!c)
|
||||
return -1;
|
||||
|
||||
for (s32 i=used-1; i>=0; --i)
|
||||
for (u32 j=0; j<count; ++j)
|
||||
if (array[i] == c[j])
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//! finds another string in this string
|
||||
//! \param str: Another string
|
||||
//! \return Returns positions where the string has been found,
|
||||
//! or -1 if not found.
|
||||
template <class B>
|
||||
s32 find(const B* const str) const
|
||||
{
|
||||
if (str && *str)
|
||||
{
|
||||
u32 len = 0;
|
||||
|
||||
while (str[len])
|
||||
++len;
|
||||
|
||||
if (len > used-1)
|
||||
return -1;
|
||||
|
||||
for (s32 i=0; i<used-len; ++i)
|
||||
{
|
||||
u32 j=0;
|
||||
|
||||
while(str[j] && array[i+j] == str[j])
|
||||
++j;
|
||||
|
||||
if (!str[j])
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//! Returns a substring
|
||||
//! \param begin: Start of substring.
|
||||
//! \param length: Length of substring.
|
||||
string<T> subString(u32 begin, s32 length) const
|
||||
{
|
||||
if ((length+begin) > size())
|
||||
length = size()-begin;
|
||||
if (length <= 0)
|
||||
return string<T>("");
|
||||
|
||||
string<T> o;
|
||||
o.reserve(length+1);
|
||||
|
||||
for (s32 i=0; i<length; ++i)
|
||||
o.array[i] = array[i+begin];
|
||||
|
||||
o.array[length] = 0;
|
||||
o.used = o.allocated;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
string<T>& operator += (T c)
|
||||
{
|
||||
append(c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
string<T>& operator += (const T* const c)
|
||||
{
|
||||
append(c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
string<T>& operator += (const string<T>& other)
|
||||
{
|
||||
append(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
string<T>& operator += (const int i)
|
||||
{
|
||||
append(string<T>(i));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
string<T>& operator += (const unsigned int i)
|
||||
{
|
||||
append(string<T>(i));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
string<T>& operator += (const long i)
|
||||
{
|
||||
append(string<T>(i));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
string<T>& operator += (const unsigned long& i)
|
||||
{
|
||||
append(string<T>(i));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
string<T>& operator += (const double i)
|
||||
{
|
||||
append(string<T>(i));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
string<T>& operator += (const float i)
|
||||
{
|
||||
append(string<T>(i));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//! replaces all characters of a special type with another one
|
||||
void replace(T toReplace, T replaceWith)
|
||||
{
|
||||
for (u32 i=0; i<used; ++i)
|
||||
if (array[i] == toReplace)
|
||||
array[i] = replaceWith;
|
||||
}
|
||||
|
||||
//! trims the string.
|
||||
/** Removes whitespace from begin and end of the string. */
|
||||
string<T>& trim()
|
||||
{
|
||||
const c8 whitespace[] = " \t\n\r";
|
||||
const u32 whitespacecount = 4;
|
||||
|
||||
// find start and end of real string without whitespace
|
||||
const s32 begin = findFirstCharNotInList(whitespace, whitespacecount);
|
||||
if (begin == -1)
|
||||
return (*this="");
|
||||
|
||||
const s32 end = findLastCharNotInList(whitespace, whitespacecount);
|
||||
|
||||
return (*this = subString(begin, (end +1) - begin));
|
||||
}
|
||||
|
||||
|
||||
//! Erases a character from the string. May be slow, because all elements
|
||||
//! following after the erased element have to be copied.
|
||||
//! \param index: Index of element to be erased.
|
||||
void erase(u32 index)
|
||||
{
|
||||
_IRR_DEBUG_BREAK_IF(index>=used) // access violation
|
||||
|
||||
for (u32 i=index+1; i<used; ++i)
|
||||
array[i-1] = array[i];
|
||||
|
||||
--used;
|
||||
}
|
||||
|
||||
private:
|
||||
/*
|
||||
T toLower(const T& t) const
|
||||
{
|
||||
if (t>=(T)'A' && t<=(T)'Z')
|
||||
return t + ((T)'a' - (T)'A');
|
||||
else
|
||||
return t;
|
||||
}
|
||||
*/
|
||||
//! Returns a character converted to lower case
|
||||
inline T ansi_lower ( u32 x ) const
|
||||
{
|
||||
return x >= 'A' && x <= 'Z' ? (T) x + 0x20 : (T) x;
|
||||
}
|
||||
|
||||
|
||||
//! Reallocate the array, make it bigger or smaller
|
||||
void reallocate(u32 new_size)
|
||||
{
|
||||
T* old_array = array;
|
||||
|
||||
array = allocator.allocate(new_size); //new T[new_size];
|
||||
allocated = new_size;
|
||||
|
||||
u32 amount = used < new_size ? used : new_size;
|
||||
for (u32 i=0; i<amount; ++i)
|
||||
array[i] = old_array[i];
|
||||
|
||||
if (allocated < used)
|
||||
used = allocated;
|
||||
|
||||
allocator.deallocate(old_array); // delete [] old_array;
|
||||
}
|
||||
|
||||
|
||||
//--- member variables
|
||||
|
||||
T* array;
|
||||
u32 allocated;
|
||||
u32 used;
|
||||
TAlloc allocator;
|
||||
};
|
||||
|
||||
|
||||
//! Typedef for character strings
|
||||
typedef string<c8> stringc;
|
||||
|
||||
//! Typedef for wide character strings
|
||||
typedef string<wchar_t> stringw;
|
||||
|
||||
} // end namespace core
|
||||
} // end namespace irr
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
// Copyright (C) 2002-2007 Nikolaus Gebhardt
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
#ifndef __IRR_TYPES_H_INCLUDED__
|
||||
#define __IRR_TYPES_H_INCLUDED__
|
||||
|
||||
|
||||
namespace irr
|
||||
{
|
||||
|
||||
//! 8 bit unsigned variable.
|
||||
/** This is a typedef for unsigned char, it ensures portability of the engine. */
|
||||
typedef unsigned char u8;
|
||||
|
||||
//! 8 bit signed variable.
|
||||
/** This is a typedef for signed char, it ensures portability of the engine. */
|
||||
typedef signed char s8;
|
||||
|
||||
//! 8 bit character variable.
|
||||
/** This is a typedef for char, it ensures portability of the engine. */
|
||||
typedef char c8;
|
||||
|
||||
|
||||
|
||||
//! 16 bit unsigned variable.
|
||||
/** This is a typedef for unsigned short, it ensures portability of the engine. */
|
||||
typedef unsigned short u16;
|
||||
|
||||
//! 16 bit signed variable.
|
||||
/** This is a typedef for signed short, it ensures portability of the engine. */
|
||||
typedef signed short s16;
|
||||
|
||||
|
||||
|
||||
//! 32 bit unsigned variable.
|
||||
/** This is a typedef for unsigned int, it ensures portability of the engine. */
|
||||
typedef unsigned int u32;
|
||||
|
||||
//! 32 bit signed variable.
|
||||
/** This is a typedef for signed int, it ensures portability of the engine. */
|
||||
typedef signed int s32;
|
||||
|
||||
|
||||
|
||||
// 64 bit signed variable.
|
||||
// This is a typedef for __int64, it ensures portability of the engine.
|
||||
// This type is currently not used by the engine and not supported by compilers
|
||||
// other than Microsoft Compilers, so it is outcommented.
|
||||
//typedef __int64 s64;
|
||||
|
||||
|
||||
|
||||
//! 32 bit floating point variable.
|
||||
/** This is a typedef for float, it ensures portability of the engine. */
|
||||
typedef float f32;
|
||||
|
||||
//! 64 bit floating point variable.
|
||||
/** This is a typedef for double, it ensures portability of the engine. */
|
||||
typedef double f64;
|
||||
|
||||
|
||||
} // end namespace irr
|
||||
|
||||
|
||||
#include <wchar.h>
|
||||
#ifdef _IRR_WINDOWS_API_
|
||||
//! Defines for s{w,n}printf because these methods do not match the ISO C
|
||||
//! standard on Windows platforms, but it does on all others.
|
||||
//! These should be int snprintf(char *str, size_t size, const char *format, ...);
|
||||
//! and int swprintf(wchar_t *wcs, size_t maxlen, const wchar_t *format, ...);
|
||||
#if defined(_MSC_VER) && _MSC_VER > 1310 && !defined (_WIN32_WCE)
|
||||
#define swprintf swprintf_s
|
||||
#define snprintf sprintf_s
|
||||
#else
|
||||
#define swprintf _snwprintf
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
// define the wchar_t type if not already built in.
|
||||
#ifdef _MSC_VER
|
||||
#ifndef _WCHAR_T_DEFINED
|
||||
//! A 16 bit wide character type.
|
||||
/**
|
||||
Defines the wchar_t-type.
|
||||
In VS6, its not possible to tell
|
||||
the standard compiler to treat wchar_t as a built-in type, and
|
||||
sometimes we just don't want to include the huge stdlib.h or wchar.h,
|
||||
so we'll use this.
|
||||
*/
|
||||
typedef unsigned short wchar_t;
|
||||
#define _WCHAR_T_DEFINED
|
||||
#endif // wchar is not defined
|
||||
#endif // microsoft compiler
|
||||
#endif // _IRR_WINDOWS_API_
|
||||
|
||||
//! define a break macro for debugging.
|
||||
#if defined(_DEBUG)
|
||||
#if defined(_IRR_WINDOWS_API_) && defined(_MSC_VER) && !defined (_WIN32_WCE)
|
||||
#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) if (_CONDITION_) {_asm int 3}
|
||||
#else
|
||||
#include "assert.h"
|
||||
#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) assert( !(_CONDITION_) );
|
||||
#endif
|
||||
#else
|
||||
#define _IRR_DEBUG_BREAK_IF( _CONDITION_ )
|
||||
#endif
|
||||
|
||||
//! Defines a small statement to work around a microsoft compiler bug.
|
||||
/** The microsft compiler 7.0 - 7.1 has a bug:
|
||||
When you call unmanaged code that returns a bool type value of false from managed code,
|
||||
the return value may appear as true. See
|
||||
http://support.microsoft.com/default.aspx?kbid=823071 for details.
|
||||
Compiler version defines: VC6.0 : 1200, VC7.0 : 1300, VC7.1 : 1310, VC8.0 : 1400*/
|
||||
#if defined(_IRR_WINDOWS_API_) && defined(_MSC_VER) && (_MSC_VER > 1299) && (_MSC_VER < 1400)
|
||||
#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX __asm mov eax,100
|
||||
#else
|
||||
#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX
|
||||
#endif // _IRR_MANAGED_MARSHALLING_BUGFIX
|
||||
|
||||
|
||||
// memory debugging
|
||||
#if defined(_DEBUG) && defined(IRRLICHT_EXPORTS) && defined(_MSC_VER) && \
|
||||
(_MSC_VER > 1299) && !defined(_IRR_DONT_DO_MEMORY_DEBUGGING_HERE) && !defined(_WIN32_WCE)
|
||||
|
||||
#define CRTDBG_MAP_ALLOC
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
|
||||
#include <stdlib.h>
|
||||
#include <crtdbg.h>
|
||||
#define new DEBUG_CLIENTBLOCK
|
||||
#endif
|
||||
|
||||
// disable truncated debug information warning in visual studio 6 by default
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1300 )
|
||||
#pragma warning( disable: 4786)
|
||||
#endif // _MSC
|
||||
|
||||
|
||||
//! ignore VC8 warning deprecated
|
||||
/** The microsoft compiler */
|
||||
#if defined(_IRR_WINDOWS_API_) && defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
//#pragma warning( disable: 4996)
|
||||
//#define _CRT_SECURE_NO_DEPRECATE 1
|
||||
//#define _CRT_NONSTDC_NO_DEPRECATE 1
|
||||
#endif
|
||||
|
||||
|
||||
//! creates four CC codes used in Irrlicht for simple ids
|
||||
/** some compilers can create those by directly writing the
|
||||
code like 'code', but some generate warnings so we use this macro here */
|
||||
#define MAKE_IRR_ID(c0, c1, c2, c3) \
|
||||
((u32)(u8)(c0) | ((u32)(u8)(c1) << 8) | \
|
||||
((u32)(u8)(c2) << 16) | ((u32)(u8)(c3) << 24 ))
|
||||
|
||||
|
||||
#endif // __IRR_TYPES_H_INCLUDED__
|
||||
|
||||
|
|
@ -0,0 +1,287 @@
|
|||
// Copyright (C) 2002-2007 Nikolaus Gebhardt
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
#ifndef __IRR_POINT_3D_H_INCLUDED__
|
||||
#define __IRR_POINT_3D_H_INCLUDED__
|
||||
|
||||
#include "irrMath.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
|
||||
//! 3d vector template class with lots of operators and methods.
|
||||
template <class T>
|
||||
class vector3d
|
||||
{
|
||||
public:
|
||||
|
||||
vector3d() : X(0), Y(0), Z(0) {}
|
||||
vector3d(T nx, T ny, T nz) : X(nx), Y(ny), Z(nz) {}
|
||||
vector3d(const vector3d<T>& other) : X(other.X), Y(other.Y), Z(other.Z) {}
|
||||
|
||||
// operators
|
||||
|
||||
vector3d<T> operator-() const { return vector3d<T>(-X, -Y, -Z); }
|
||||
|
||||
vector3d<T>& operator=(const vector3d<T>& other) { X = other.X; Y = other.Y; Z = other.Z; return *this; }
|
||||
|
||||
vector3d<T> operator+(const vector3d<T>& other) const { return vector3d<T>(X + other.X, Y + other.Y, Z + other.Z); }
|
||||
vector3d<T>& operator+=(const vector3d<T>& other) { X+=other.X; Y+=other.Y; Z+=other.Z; return *this; }
|
||||
|
||||
vector3d<T> operator-(const vector3d<T>& other) const { return vector3d<T>(X - other.X, Y - other.Y, Z - other.Z); }
|
||||
vector3d<T>& operator-=(const vector3d<T>& other) { X-=other.X; Y-=other.Y; Z-=other.Z; return *this; }
|
||||
|
||||
vector3d<T> operator*(const vector3d<T>& other) const { return vector3d<T>(X * other.X, Y * other.Y, Z * other.Z); }
|
||||
vector3d<T>& operator*=(const vector3d<T>& other) { X*=other.X; Y*=other.Y; Z*=other.Z; return *this; }
|
||||
vector3d<T> operator*(const T v) const { return vector3d<T>(X * v, Y * v, Z * v); }
|
||||
vector3d<T>& operator*=(const T v) { X*=v; Y*=v; Z*=v; return *this; }
|
||||
|
||||
vector3d<T> operator/(const vector3d<T>& other) const { return vector3d<T>(X / other.X, Y / other.Y, Z / other.Z); }
|
||||
vector3d<T>& operator/=(const vector3d<T>& other) { X/=other.X; Y/=other.Y; Z/=other.Z; return *this; }
|
||||
vector3d<T> operator/(const T v) const { T i=(T)1.0/v; return vector3d<T>(X * i, Y * i, Z * i); }
|
||||
vector3d<T>& operator/=(const T v) { T i=(T)1.0/v; X*=i; Y*=i; Z*=i; return *this; }
|
||||
|
||||
bool operator<=(const vector3d<T>&other) const { return X<=other.X && Y<=other.Y && Z<=other.Z;};
|
||||
bool operator>=(const vector3d<T>&other) const { return X>=other.X && Y>=other.Y && Z>=other.Z;};
|
||||
bool operator<(const vector3d<T>&other) const { return X<other.X && Y<other.Y && Z<other.Z;};
|
||||
bool operator>(const vector3d<T>&other) const { return X>other.X && Y>other.Y && Z>other.Z;};
|
||||
|
||||
//! use week float compare
|
||||
//bool operator==(const vector3d<T>& other) const { return other.X==X && other.Y==Y && other.Z==Z; }
|
||||
//bool operator!=(const vector3d<T>& other) const { return other.X!=X || other.Y!=Y || other.Z!=Z; }
|
||||
|
||||
bool operator==(const vector3d<T>& other) const
|
||||
{
|
||||
return this->equals(other);
|
||||
}
|
||||
|
||||
bool operator!=(const vector3d<T>& other) const
|
||||
{
|
||||
return !this->equals(other);
|
||||
}
|
||||
|
||||
// functions
|
||||
|
||||
//! returns if this vector equals the other one, taking floating point rounding errors into account
|
||||
bool equals(const vector3d<T>& other, const T tolerance = (T)ROUNDING_ERROR_32 ) const
|
||||
{
|
||||
return core::equals(X, other.X, tolerance) &&
|
||||
core::equals(Y, other.Y, tolerance) &&
|
||||
core::equals(Z, other.Z, tolerance);
|
||||
}
|
||||
|
||||
vector3d<T>& set(const T nx, const T ny, const T nz) {X=nx; Y=ny; Z=nz; return *this;}
|
||||
vector3d<T>& set(const vector3d<T>& p) {X=p.X; Y=p.Y; Z=p.Z;return *this;}
|
||||
|
||||
//! Returns length of the vector.
|
||||
T getLength() const { return (T) sqrt((f64)(X*X + Y*Y + Z*Z)); }
|
||||
|
||||
//! Returns squared length of the vector.
|
||||
/** This is useful because it is much faster than
|
||||
getLength(). */
|
||||
T getLengthSQ() const { return X*X + Y*Y + Z*Z; }
|
||||
|
||||
//! Returns the dot product with another vector.
|
||||
T dotProduct(const vector3d<T>& other) const
|
||||
{
|
||||
return X*other.X + Y*other.Y + Z*other.Z;
|
||||
}
|
||||
|
||||
//! Returns distance from another point.
|
||||
/** Here, the vector is interpreted as point in 3 dimensional space. */
|
||||
T getDistanceFrom(const vector3d<T>& other) const
|
||||
{
|
||||
return vector3d<T>(X - other.X, Y - other.Y, Z - other.Z).getLength();
|
||||
}
|
||||
|
||||
//! Returns squared distance from another point.
|
||||
/** Here, the vector is interpreted as point in 3 dimensional space. */
|
||||
T getDistanceFromSQ(const vector3d<T>& other) const
|
||||
{
|
||||
return vector3d<T>(X - other.X, Y - other.Y, Z - other.Z).getLengthSQ();
|
||||
}
|
||||
|
||||
//! Calculates the cross product with another vector
|
||||
//! \param p: vector to multiply with.
|
||||
//! \return Crossproduct of this vector with p.
|
||||
vector3d<T> crossProduct(const vector3d<T>& p) const
|
||||
{
|
||||
return vector3d<T>(Y * p.Z - Z * p.Y, Z * p.X - X * p.Z, X * p.Y - Y * p.X);
|
||||
}
|
||||
|
||||
//! Returns if this vector interpreted as a point is on a line between two other points.
|
||||
/** It is assumed that the point is on the line. */
|
||||
//! \param begin: Beginning vector to compare between.
|
||||
//! \param end: Ending vector to compare between.
|
||||
//! \return True if this vector is between begin and end. False if not.
|
||||
bool isBetweenPoints(const vector3d<T>& begin, const vector3d<T>& end) const
|
||||
{
|
||||
T f = (end - begin).getLengthSQ();
|
||||
return getDistanceFromSQ(begin) < f &&
|
||||
getDistanceFromSQ(end) < f;
|
||||
}
|
||||
|
||||
//! Normalizes the vector. In case of the 0 vector the result
|
||||
//! is still 0, otherwise the length of the vector will be 1.
|
||||
//! Todo: 64 Bit template doesnt work.. need specialized template
|
||||
vector3d<T>& normalize()
|
||||
{
|
||||
T l = X*X + Y*Y + Z*Z;
|
||||
if (l == 0)
|
||||
return *this;
|
||||
l = (T) reciprocal_squareroot ( (f32)l );
|
||||
X *= l;
|
||||
Y *= l;
|
||||
Z *= l;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Sets the length of the vector to a new value
|
||||
vector3d<T>& setLength(T newlength)
|
||||
{
|
||||
normalize();
|
||||
return (*this *= newlength);
|
||||
}
|
||||
|
||||
//! Inverts the vector.
|
||||
vector3d<T>& invert()
|
||||
{
|
||||
X *= -1.0f;
|
||||
Y *= -1.0f;
|
||||
Z *= -1.0f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Rotates the vector by a specified number of degrees around the Y
|
||||
//! axis and the specified center.
|
||||
//! \param degrees: Number of degrees to rotate around the Y axis.
|
||||
//! \param center: The center of the rotation.
|
||||
void rotateXZBy(f64 degrees, const vector3d<T>& center=vector3d<T>())
|
||||
{
|
||||
degrees *= DEGTORAD64;
|
||||
T cs = (T)cos(degrees);
|
||||
T sn = (T)sin(degrees);
|
||||
X -= center.X;
|
||||
Z -= center.Z;
|
||||
set(X*cs - Z*sn, Y, X*sn + Z*cs);
|
||||
X += center.X;
|
||||
Z += center.Z;
|
||||
}
|
||||
|
||||
//! Rotates the vector by a specified number of degrees around the Z
|
||||
//! axis and the specified center.
|
||||
//! \param degrees: Number of degrees to rotate around the Z axis.
|
||||
//! \param center: The center of the rotation.
|
||||
void rotateXYBy(f64 degrees, const vector3d<T>& center=vector3d<T>())
|
||||
{
|
||||
degrees *= DEGTORAD64;
|
||||
T cs = (T)cos(degrees);
|
||||
T sn = (T)sin(degrees);
|
||||
X -= center.X;
|
||||
Y -= center.Y;
|
||||
set(X*cs - Y*sn, X*sn + Y*cs, Z);
|
||||
X += center.X;
|
||||
Y += center.Y;
|
||||
}
|
||||
|
||||
//! Rotates the vector by a specified number of degrees around the X
|
||||
//! axis and the specified center.
|
||||
//! \param degrees: Number of degrees to rotate around the X axis.
|
||||
//! \param center: The center of the rotation.
|
||||
void rotateYZBy(f64 degrees, const vector3d<T>& center=vector3d<T>())
|
||||
{
|
||||
degrees *= DEGTORAD64;
|
||||
T cs = (T)cos(degrees);
|
||||
T sn = (T)sin(degrees);
|
||||
Z -= center.Z;
|
||||
Y -= center.Y;
|
||||
set(X, Y*cs - Z*sn, Y*sn + Z*cs);
|
||||
Z += center.Z;
|
||||
Y += center.Y;
|
||||
}
|
||||
|
||||
//! Returns interpolated vector.
|
||||
/** \param other: other vector to interpolate between
|
||||
\param d: value between 0.0f and 1.0f. */
|
||||
vector3d<T> getInterpolated(const vector3d<T>& other, const T d) const
|
||||
{
|
||||
const T inv = (T) 1.0 - d;
|
||||
return vector3d<T>(other.X*inv + X*d, other.Y*inv + Y*d, other.Z*inv + Z*d);
|
||||
}
|
||||
|
||||
//! Returns interpolated vector. ( quadratic )
|
||||
/** \param v2: second vector to interpolate with
|
||||
\param v3: third vector to interpolate with
|
||||
\param d: value between 0.0f and 1.0f. */
|
||||
vector3d<T> getInterpolated_quadratic(const vector3d<T>& v2, const vector3d<T>& v3, const T d) const
|
||||
{
|
||||
// this*(1-d)*(1-d) + 2 * v2 * (1-d) + v3 * d * d;
|
||||
const T inv = (T) 1.0 - d;
|
||||
const T mul0 = inv * inv;
|
||||
const T mul1 = (T) 2.0 * d * inv;
|
||||
const T mul2 = d * d;
|
||||
|
||||
return vector3d<T> ( X * mul0 + v2.X * mul1 + v3.X * mul2,
|
||||
Y * mul0 + v2.Y * mul1 + v3.Y * mul2,
|
||||
Z * mul0 + v2.Z * mul1 + v3.Z * mul2);
|
||||
}
|
||||
|
||||
//! Gets the Y and Z rotations of a vector.
|
||||
/** Thanks to Arras on the Irrlicht forums to add this method.
|
||||
\return A vector representing the rotation in degrees of
|
||||
this vector. The Z component of the vector will always be 0. */
|
||||
vector3d<T> getHorizontalAngle() const
|
||||
{
|
||||
vector3d<T> angle;
|
||||
|
||||
angle.Y = (T)atan2(X, Z);
|
||||
angle.Y *= (f32)RADTODEG64;
|
||||
|
||||
if (angle.Y < 0.0f) angle.Y += 360.0f;
|
||||
if (angle.Y >= 360.0f) angle.Y -= 360.0f;
|
||||
|
||||
const f32 z1 = sqrtf(X*X + Z*Z);
|
||||
|
||||
angle.X = (T)atan2f(z1, (f32)Y);
|
||||
angle.X *= RADTODEG;
|
||||
angle.X -= 90.0f;
|
||||
|
||||
if (angle.X < 0.0f) angle.X += 360.0f;
|
||||
if (angle.X >= 360.0f) angle.X -= 360.0f;
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
//! Fills an array of 4 values with the vector data (usually floats).
|
||||
/** Useful for setting in shader constants for example. The fourth value
|
||||
will always be 0. */
|
||||
void getAs4Values(T* array) const
|
||||
{
|
||||
array[0] = X;
|
||||
array[1] = Y;
|
||||
array[2] = Z;
|
||||
array[3] = 0;
|
||||
}
|
||||
|
||||
// member variables
|
||||
|
||||
T X, Y, Z;
|
||||
};
|
||||
|
||||
|
||||
//! Typedef for a f32 3d vector.
|
||||
typedef vector3d<f32> vector3df;
|
||||
//! Typedef for an integer 3d vector.
|
||||
typedef vector3d<s32> vector3di;
|
||||
|
||||
template<class S, class T>
|
||||
vector3d<T> operator*(const S scalar, const vector3d<T>& vector) { return vector*scalar; }
|
||||
|
||||
} // end namespace core
|
||||
} // end namespace irr
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
#ifndef NET_PACKET_H
|
||||
#define NET_PACKET_H
|
||||
|
||||
#ifdef COMPILE_WITH_IRRLICHT
|
||||
#include <irrlicht.h>
|
||||
#endif
|
||||
|
||||
#ifndef IRRLICHT_SDK_VERSION
|
||||
#include "NoIrrlicht/NoIrrlicht.h"
|
||||
#endif
|
||||
|
||||
#ifndef s64
|
||||
typedef signed long long s64;
|
||||
#endif
|
||||
|
||||
#ifndef u64
|
||||
typedef signed long long u64;
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace net
|
||||
{
|
||||
|
||||
/// An SOutPacket class, used for sending packets.
|
||||
class SOutPacket
|
||||
{
|
||||
public:
|
||||
SOutPacket();
|
||||
SOutPacket(const c8* buff,const u32 buff_size);
|
||||
|
||||
/// Adds data to the packet.
|
||||
SOutPacket& operator << (const c8 data);
|
||||
/// Adds data to the packet.
|
||||
SOutPacket& operator << (const u16 data);
|
||||
/// Adds data to the packet.
|
||||
SOutPacket& operator << (const u32 data);
|
||||
/// Adds data to the packet.
|
||||
SOutPacket& operator << (const u8 data);
|
||||
/// Adds data to the packet.
|
||||
SOutPacket& operator << (const s16 data);
|
||||
/// Adds data to the packet.
|
||||
SOutPacket& operator << (const s32 data);
|
||||
/// Adds data to the packet.
|
||||
SOutPacket& operator << (const f32 data);
|
||||
/// Adds data to the packet.
|
||||
SOutPacket& operator << (const f64 data);
|
||||
/// Adds data to the packet.
|
||||
SOutPacket& operator << (const core::vector3df& data);
|
||||
/// Adds data to the packet.
|
||||
SOutPacket& operator << (const c8* string);
|
||||
/// Adds data to the packet.
|
||||
SOutPacket& operator << (const core::stringc& string);
|
||||
/// Adds data to the packet.
|
||||
SOutPacket& operator << (const std::string& string);
|
||||
/// Adds data to the packet.
|
||||
SOutPacket& operator << (const core::stringw& string);
|
||||
|
||||
/// Appends another SOutPacket to the packet.
|
||||
SOutPacket& operator << (const SOutPacket& other);
|
||||
|
||||
/// Clears the data in the packet. (Resets the write position)
|
||||
void clearData();
|
||||
|
||||
/// Gets the data in the packet.
|
||||
c8* getData();
|
||||
|
||||
/// Gets the data in the packet.
|
||||
const c8* getConstData();
|
||||
|
||||
/// Returns the size in bytes of the packet.
|
||||
u32 getSize();
|
||||
|
||||
/// Compresses the packet using zlib compression.
|
||||
void compressPacket();
|
||||
|
||||
/// Decompresses the packet using zlib decompression.
|
||||
void deCompressPacket();
|
||||
|
||||
/// Encrypts a packet using AES encryption.
|
||||
void encryptPacket(const c8 key[16]);
|
||||
|
||||
/// Decrypts a packet using AES decryption.
|
||||
void decryptPacket(const c8 key[16]);
|
||||
private:
|
||||
void enlargeBuffer(const u32 size);
|
||||
core::array<c8> buff;
|
||||
};
|
||||
|
||||
/// An SInPacket class, used for handling recieved packets.
|
||||
class SInPacket
|
||||
{
|
||||
public:
|
||||
SInPacket(const c8* buff, const u32 size);
|
||||
|
||||
void setNewData(const c8* buffer, const u32 size);
|
||||
|
||||
/// Gets the next item in the packet based on the size of the variable.
|
||||
void operator >> (c8& data);
|
||||
/// Gets the next item in the packet based on the size of the variable.
|
||||
void operator >> (u16& data);
|
||||
/// Gets the next item in the packet based on the size of the variable.
|
||||
void operator >> (u32& data);
|
||||
/// Gets the next item in the packet based on the size of the variable.
|
||||
void operator >> (u8& data);
|
||||
/// Gets the next item in the packet based on the size of the variable.
|
||||
void operator >> (s16& data);
|
||||
/// Gets the next item in the packet based on the size of the variable.
|
||||
void operator >> (s32& data);
|
||||
/// Gets the next item in the packet based on the size of the variable.
|
||||
void operator >> (f32& data);
|
||||
/// Gets the next item in the packet based on the size of the variable.
|
||||
void operator >> (f64& data);
|
||||
/// Gets the next item in the packet based on the size of the variable.
|
||||
void operator >> (core::vector3df& data);
|
||||
/// Gets the next item in the packet based on the size of the variable.
|
||||
void operator >> (char* string);
|
||||
/// Gets the next item in the packet based on the size of the variable.
|
||||
void operator >> (core::stringc& string);
|
||||
/// Gets the next item in the packet based on the size of the variable.
|
||||
void operator >> (std::string& string);
|
||||
/// Gets the next item in the packet based on the size of the variable.
|
||||
void operator >> (core::stringw& string);
|
||||
|
||||
/// Gets the data in the packet.
|
||||
c8* getData();
|
||||
|
||||
/// Gets the data in the packet.
|
||||
const c8* getConstData();
|
||||
|
||||
/// Resets the read position.
|
||||
void resetPos();
|
||||
|
||||
/// Returns the player ID of the player that sent this packet. (Only for servers)
|
||||
u16 getPlayerId() const;
|
||||
|
||||
// Used internally by irrNetLite to set the player ID.
|
||||
void setPlayerId(u16 playernumber);
|
||||
|
||||
/// Compresses the packet using zlib compression.
|
||||
void compressPacket();
|
||||
|
||||
/// Decompresses the packet using zlib decompression.
|
||||
void deCompressPacket();
|
||||
|
||||
/// Encrypts a packet using AES encryption.
|
||||
void encryptPacket(const c8 key[16]);
|
||||
|
||||
/// Decrypts a packet using AES decryption.
|
||||
void decryptPacket(const c8 key[16]);
|
||||
|
||||
/// Returns the size in bytes of the packet.
|
||||
u32 getSize();
|
||||
|
||||
private:
|
||||
u32 pos;
|
||||
core::array<c8> buff;
|
||||
u16 playerid;
|
||||
};
|
||||
|
||||
} // Close Net Namespace
|
||||
} // Close Irr namespace
|
||||
|
||||
#endif
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef IRRNET_H
|
||||
#define IRRNET_H
|
||||
#include "SPacket.h"
|
||||
#include "INetManager.h"
|
||||
#endif
|
||||
|
||||
// Copyright(C) Ahmed Hilali 2007
|
||||
|
||||
/* License:
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgement in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be clearly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
*/
|
||||
|
Binary file not shown.
|
@ -0,0 +1,57 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
project(enet)
|
||||
|
||||
# The "configure" step.
|
||||
include(CheckFunctionExists)
|
||||
include(CheckStructHasMember)
|
||||
include(CheckTypeSize)
|
||||
check_function_exists("fcntl" HAS_FCNTL)
|
||||
check_function_exists("poll" HAS_POLL)
|
||||
check_function_exists("gethostbyname_r" HAS_GETHOSTBYNAME_R)
|
||||
check_function_exists("gethostbyaddr_r" HAS_GETHOSTBYADDR_R)
|
||||
check_function_exists("inet_pton" HAS_INET_PTON)
|
||||
check_function_exists("inet_ntop" HAS_INET_NTOP)
|
||||
check_struct_has_member("struct msghdr" "msg_flags" "sys/types.h;sys/socket.h" HAS_MSGHDR_FLAGS)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "sys/types.h" "sys/socket.h")
|
||||
check_type_size("socklen_t" HAS_SOCKLEN_T BUILTIN_TYPES_ONLY)
|
||||
unset(CMAKE_EXTRA_INCLUDE_FILES)
|
||||
|
||||
if(HAS_FCNTL)
|
||||
add_definitions(-DHAS_FCNTL=1)
|
||||
endif()
|
||||
if(HAS_POLL)
|
||||
add_definitions(-DHAS_POLL=1)
|
||||
endif()
|
||||
if(HAS_GETHOSTBYNAME_R)
|
||||
add_definitions(-DHAS_GETHOSTBYNAME_R=1)
|
||||
endif()
|
||||
if(HAS_GETHOSTBYADDR_R)
|
||||
add_definitions(-DHAS_GETHOSTBYADDR_R=1)
|
||||
endif()
|
||||
if(HAS_INET_PTON)
|
||||
add_definitions(-DHAS_INET_PTON=1)
|
||||
endif()
|
||||
if(HAS_INET_NTOP)
|
||||
add_definitions(-DHAS_INET_NTOP=1)
|
||||
endif()
|
||||
if(HAS_MSGHDR_FLAGS)
|
||||
add_definitions(-DHAS_MSGHDR_FLAGS=1)
|
||||
endif()
|
||||
if(HAS_SOCKLEN_T)
|
||||
add_definitions(-DHAS_SOCKLEN_T=1)
|
||||
endif()
|
||||
|
||||
include_directories(${PROJECT_SOURCE_DIR}/include)
|
||||
|
||||
add_library(enet STATIC
|
||||
callbacks.c
|
||||
compress.c
|
||||
host.c
|
||||
list.c
|
||||
packet.c
|
||||
peer.c
|
||||
protocol.c
|
||||
unix.c
|
||||
win32.c
|
||||
)
|
|
@ -0,0 +1,463 @@
|
|||
#include "CNetManager.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace net
|
||||
{
|
||||
CNetManager::CNetManager(INetCallback* handler, u32 port, const SNetParams& params) :
|
||||
pHandler(handler), netIterations(10000), netParams(params), verbose(0),
|
||||
globPacketRelay(false), connectionStatus(EICS_PENDING)
|
||||
{
|
||||
if (enet_initialize() != 0)
|
||||
std::cout << "irrNetLite: An error occurred while initializing ENet.\n";
|
||||
|
||||
connectionStatus = setUpServer(port) ? EICS_ESTABLISHED : EICS_FAILED;
|
||||
}
|
||||
|
||||
CNetManager::CNetManager(INetCallback* handler, const c8* addressc,
|
||||
const u32 port, const SNetParams& params) :
|
||||
pHandler(handler), netIterations(10000), netParams(params), verbose(0),
|
||||
globPacketRelay(false), connectionStatus(EICS_PENDING)
|
||||
{
|
||||
if (enet_initialize() != 0)
|
||||
std::cout << "irrNetLite: An error occurred while initializing ENet.\n";
|
||||
|
||||
if(!setUpClient(addressc, port))
|
||||
connectionStatus = EICS_FAILED;
|
||||
}
|
||||
|
||||
CNetManager::~CNetManager(void)
|
||||
{
|
||||
if(host)
|
||||
enet_host_destroy(host);
|
||||
|
||||
enet_deinitialize();
|
||||
}
|
||||
|
||||
bool CNetManager::setUpClient(const c8* addressc, const u32 port)
|
||||
{
|
||||
mode = ENM_CLIENT;
|
||||
|
||||
if(verbose)
|
||||
std::cout << "irrNetLite: Creating client!" << std::endl;
|
||||
|
||||
host = enet_host_create(NULL, 1,2, netParams.downBandwidth / 8, netParams.upBandwidth / 8);
|
||||
|
||||
ENetEvent event;
|
||||
|
||||
enet_address_set_host(&address, addressc);
|
||||
address.port = port;
|
||||
|
||||
if(verbose)
|
||||
std::cout << "irrNetLite: Connecting to "
|
||||
<< addressc << ":" << port << std::endl;
|
||||
|
||||
// Sets up two channels.
|
||||
peer = enet_host_connect(host, &address, 2, 0);
|
||||
|
||||
if(peer == NULL)
|
||||
{
|
||||
std::cout << "irrNetLite: Error: Could not resolve server address. Connection failed.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!( enet_host_service(host, &event, netParams.connectionTimeout) > 0 &&
|
||||
event.type == ENET_EVENT_TYPE_CONNECT))
|
||||
{
|
||||
enet_peer_reset(peer);
|
||||
|
||||
std::cout << "irrNetLite: Error: Connection timed out. Connection failed.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
while(enet_host_service(host, &event, netParams.connectionTimeout) > 0)
|
||||
{
|
||||
if(event.channelID == 1 && event.type == ENET_EVENT_TYPE_RECEIVE)
|
||||
{
|
||||
enet_uint8* buff = event.packet->data;
|
||||
|
||||
u8 packiden = 0;
|
||||
memcpy((char*)&packiden, buff, 1);
|
||||
|
||||
if(packiden == 4)
|
||||
{
|
||||
memcpy((char*)&playerID, buff+1, 2);
|
||||
|
||||
if(playerID == 0)
|
||||
{
|
||||
std::cout << "irrNetLite: Error: Null player ID recieved. Server likely full.";
|
||||
enet_peer_reset(event.peer);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(verbose)
|
||||
std::cout << "irrNetLite: Player ID is " << playerID << ".\n";
|
||||
|
||||
u8 packid = 3;
|
||||
ENetPacket* packet = enet_packet_create(&packid, 1, ENET_PACKET_FLAG_RELIABLE);
|
||||
enet_host_broadcast(host, 1, packet);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "irrNetLite: Error: Failed to recieve Player ID. Connection failed.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CNetManager::setUpServer(const u32 port)
|
||||
{
|
||||
mode = ENM_SERVER;
|
||||
netParams.maxClients++;
|
||||
|
||||
address.host = ENET_HOST_ANY;
|
||||
address.port = port;
|
||||
|
||||
if(verbose)
|
||||
std::cout << "irrNetLite: Creating server!\n";
|
||||
|
||||
host = enet_host_create(&address, netParams.maxClients,2, 0,0);
|
||||
|
||||
if(host == NULL)
|
||||
{
|
||||
std::cout << "irrNetLite: Error: An error occurred while trying to create an ENet server host.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
players.resize(netParams.maxClients, 0);
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CNetManager::setGlobalPacketRelay(bool relay)
|
||||
{
|
||||
globPacketRelay = relay;
|
||||
}
|
||||
|
||||
void CNetManager::update(const u32 timeOut)
|
||||
{
|
||||
if(connectionStatus == EICS_FAILED)
|
||||
return;
|
||||
|
||||
|
||||
if(mode == ENM_CLIENT)
|
||||
{
|
||||
ENetEvent event;
|
||||
|
||||
for(u32 i = 0; i < netIterations;i++)
|
||||
{
|
||||
if(!(enet_host_service(host, &event, i ? 1 : timeOut) > 0))
|
||||
break;
|
||||
|
||||
switch (event.type)
|
||||
{
|
||||
case ENET_EVENT_TYPE_RECEIVE:
|
||||
{
|
||||
enet_uint8* buff = event.packet->data;
|
||||
|
||||
if(event.channelID == 1)
|
||||
{
|
||||
u8 packiden = 0;
|
||||
memcpy((char*)&packiden,buff,1);
|
||||
|
||||
if(packiden == 3)
|
||||
{
|
||||
connectionStatus = EICS_ESTABLISHED;
|
||||
if(pHandler) pHandler->onConnect(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(verbose)
|
||||
std::cout << "irrNetLite: A packet of length "
|
||||
<< event.packet->dataLength
|
||||
<< " was received.\n";
|
||||
|
||||
SInPacket inpacket((c8*)buff, (u32)event.packet->dataLength);
|
||||
|
||||
if(pHandler)
|
||||
pHandler->handlePacket(inpacket);
|
||||
}
|
||||
|
||||
buff = 0;
|
||||
enet_packet_destroy(event.packet);
|
||||
break;
|
||||
}
|
||||
case ENET_EVENT_TYPE_DISCONNECT:
|
||||
std::cout << "irrNetLite: Connection to server lost.\n";
|
||||
|
||||
event.peer->data = 0;
|
||||
connectionStatus = EICS_FAILED;
|
||||
|
||||
if(pHandler)
|
||||
pHandler->onDisconnect(0);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else // (mode == ENM_SERVER)
|
||||
{
|
||||
ENetEvent event;
|
||||
|
||||
for(u32 i = 0;i < netIterations;i++)
|
||||
{
|
||||
if(!(enet_host_service (host, &event, i ? 1 : timeOut) > 0))
|
||||
break;
|
||||
|
||||
switch (event.type)
|
||||
{
|
||||
case ENET_EVENT_TYPE_CONNECT:
|
||||
{
|
||||
if(verbose)
|
||||
std::cout << "irrNetLite: A new client connected from "
|
||||
<< event.peer->address.host << ":"
|
||||
<< event.peer->address.port << std::endl;
|
||||
|
||||
u16 pID = 1;
|
||||
|
||||
while(pID < netParams.maxClients && players[pID] != 0)
|
||||
pID++;
|
||||
|
||||
if(pID >= netParams.maxClients)
|
||||
{
|
||||
if(verbose)
|
||||
std::cout << "irrNetLite: Warning: Client rejected. Too many clients."
|
||||
<< std::endl;
|
||||
|
||||
pID = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
event.peer->data = players[pID] = new SPeerData(pID, event.peer);
|
||||
}
|
||||
|
||||
c8 buffer[3];
|
||||
u8 packid = 4;
|
||||
memcpy(buffer, (char*)&packid, 1);
|
||||
memcpy(buffer+1, (char*)&pID, 2);
|
||||
ENetPacket* packet;
|
||||
packet = enet_packet_create(buffer, 3, ENET_PACKET_FLAG_RELIABLE);
|
||||
enet_peer_send(event.peer, 1, packet);
|
||||
enet_host_flush(host);
|
||||
|
||||
if(pID == 0) enet_peer_reset(event.peer);
|
||||
|
||||
break;
|
||||
}
|
||||
case ENET_EVENT_TYPE_RECEIVE:
|
||||
{
|
||||
enet_uint8* buff = event.packet->data;
|
||||
|
||||
if(event.channelID == 1)
|
||||
{
|
||||
u8 packiden = 0;
|
||||
memcpy((char*)&packiden, buff, 1);
|
||||
|
||||
if(packiden == 3)
|
||||
{
|
||||
ENetPacket* packet = enet_packet_create(&packiden, 1, ENET_PACKET_FLAG_RELIABLE);
|
||||
enet_peer_send(event.peer, 1, packet);
|
||||
SPeerData* currentPeer = reinterpret_cast<SPeerData*>(event.peer->data);
|
||||
if(currentPeer && pHandler) pHandler->onConnect(currentPeer->playerID);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SPeerData* currentPeer = reinterpret_cast<SPeerData*>(event.peer->data);
|
||||
|
||||
if(currentPeer)
|
||||
{
|
||||
SInPacket inPacket((c8*)buff, (u32)event.packet->dataLength);
|
||||
inPacket.setPlayerId(currentPeer->playerID);
|
||||
|
||||
if(verbose)
|
||||
std::cout << "irrNetLite: A packet of length "
|
||||
<< event.packet->dataLength
|
||||
<< " from player number "
|
||||
<< currentPeer->playerID
|
||||
<< " was received.\n";
|
||||
|
||||
if(pHandler)
|
||||
pHandler->handlePacket(inPacket);
|
||||
|
||||
if(globPacketRelay)
|
||||
{
|
||||
SOutPacket relayPacket((c8*)buff, (u32)event.packet->dataLength);
|
||||
|
||||
const u32 playersSize = (u32)players.size();
|
||||
for(u32 i = 0;i < playersSize;++i)
|
||||
if(players[i] && players[i] != currentPeer)
|
||||
sendOutPacket(relayPacket, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buff = 0;
|
||||
enet_packet_destroy(event.packet);
|
||||
break;
|
||||
}
|
||||
case ENET_EVENT_TYPE_DISCONNECT:
|
||||
{
|
||||
SPeerData* pData = reinterpret_cast<SPeerData*>(event.peer->data);
|
||||
|
||||
if(pData)
|
||||
{
|
||||
if(verbose)
|
||||
std::cout << "irrNetLite: Player number "
|
||||
<< pData->playerID
|
||||
<< " disconnected.\n";
|
||||
|
||||
if(pHandler) pHandler->onDisconnect(pData->playerID);
|
||||
|
||||
players[pData->playerID] = 0;
|
||||
delete pData;
|
||||
event.peer->data = 0;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CNetManager::setVerbose(bool isverbose)
|
||||
{
|
||||
verbose = isverbose;
|
||||
}
|
||||
|
||||
ENetPeer* CNetManager::getPlayerById(u16 id)
|
||||
{
|
||||
if(id < players.size() && players[id] && players[id]->playerID == id)
|
||||
return players[id]->enetPeer;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ENetPeer* CNetManager::getPeer()
|
||||
{
|
||||
if(connectionStatus == EICS_ESTABLISHED)
|
||||
return &host->peers[0];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
const u32 CNetManager::getPing()
|
||||
{
|
||||
if(getPeer())
|
||||
return getPeer()->roundTripTime;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
const u32 CNetManager::getPeerCount()
|
||||
{
|
||||
return (u32)host->peerCount;
|
||||
}
|
||||
|
||||
const u16 CNetManager::getPlayerNumber()
|
||||
{
|
||||
return playerID;
|
||||
}
|
||||
|
||||
ENetHost* CNetManager::getHost()
|
||||
{
|
||||
return host;
|
||||
}
|
||||
|
||||
E_IRRNET_CONNECTION_STATUS CNetManager::getConnectionStatus()
|
||||
{
|
||||
return connectionStatus;
|
||||
}
|
||||
|
||||
void CNetManager::kickClient(const u16 playerId, bool hardKick = false)
|
||||
{
|
||||
ENetPeer* currentPeer = getPlayerById(playerId);
|
||||
|
||||
if(currentPeer)
|
||||
hardKick ? enet_peer_disconnect_now(currentPeer,0) :
|
||||
enet_peer_disconnect(currentPeer,0);
|
||||
}
|
||||
|
||||
const u32 CNetManager::getClientAddress(const u16 playerId)
|
||||
{
|
||||
ENetPeer* currentPeer = getPlayerById(playerId);
|
||||
|
||||
if(currentPeer)
|
||||
return currentPeer->address.host;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CNetManager::sendOutPacket(SOutPacket& outpacket)
|
||||
{
|
||||
ENetPacket* packet = enet_packet_create((char*)outpacket.getData(), outpacket.getSize(),
|
||||
ENET_PACKET_FLAG_RELIABLE);
|
||||
|
||||
enet_host_broadcast(host, 0, packet);
|
||||
}
|
||||
|
||||
void CNetManager::sendOutPacket(SOutPacket& outpacket, const u16 playerId)
|
||||
{
|
||||
ENetPacket* packet = enet_packet_create ((char*)outpacket.getData(), outpacket.getSize(),
|
||||
ENET_PACKET_FLAG_RELIABLE);
|
||||
ENetPeer* currentPeer = getPlayerById(playerId);
|
||||
|
||||
if(currentPeer && currentPeer->state == ENET_PEER_STATE_CONNECTED)
|
||||
enet_peer_send(currentPeer, 0, packet);
|
||||
}
|
||||
|
||||
void CNetManager::sendOutPacketUnreliable(SOutPacket& outpacket)
|
||||
{
|
||||
ENetPacket* packet = enet_packet_create((char*)outpacket.getData(), outpacket.getSize(), 0);
|
||||
enet_host_broadcast(host, 0, packet);
|
||||
}
|
||||
|
||||
void CNetManager::sendOutPacketUnreliable(SOutPacket& outpacket, const u16 playerId)
|
||||
{
|
||||
ENetPacket* packet = enet_packet_create((char*)outpacket.getData(), outpacket.getSize(), 0);
|
||||
ENetPeer* currentPeer = getPlayerById(playerId);
|
||||
|
||||
if(currentPeer && currentPeer->state == ENET_PEER_STATE_CONNECTED)
|
||||
enet_peer_send(currentPeer, 0, packet);
|
||||
}
|
||||
|
||||
extern INetManager* createIrrNetClient(INetCallback* callback, const c8* addressc, const u32 port, const SNetParams& params)
|
||||
{
|
||||
return new irr::net::CNetManager(callback, addressc, port, params);
|
||||
}
|
||||
extern INetManager* createIrrNetServer(INetCallback* callback, const u32 port, const SNetParams& params)
|
||||
{
|
||||
return new irr::net::CNetManager(callback, port, params);
|
||||
}
|
||||
|
||||
} // Close Net Namespace
|
||||
} // Close Irr namespace
|
||||
|
||||
// Copyright(C) Ahmed Hilali 2007
|
||||
|
||||
/* License:
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgement in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be clearly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
*/
|
|
@ -0,0 +1,10 @@
|
|||
CNetManager.o: CNetManager.cpp ../include/CNetManager.h \
|
||||
../include/INetManager.h ../include/SPacket.h \
|
||||
../include/NoIrrlicht/NoIrrlicht.h ../include/NoIrrlicht/irrTypes.h \
|
||||
../include/NoIrrlicht/irrArray.h ../include/NoIrrlicht/heapsort.h \
|
||||
../include/NoIrrlicht/irrAllocator.h ../include/NoIrrlicht/irrString.h \
|
||||
../include/NoIrrlicht/irrMath.h ../include/NoIrrlicht/IrrCompileConfig.h \
|
||||
../include/NoIrrlicht/vector3d.h ../enet/include/enet/enet.h \
|
||||
../enet/include/enet/unix.h ../enet/include/enet/types.h \
|
||||
../enet/include/enet/protocol.h ../enet/include/enet/list.h \
|
||||
../enet/include/enet/callbacks.h
|
Binary file not shown.
|
@ -0,0 +1,56 @@
|
|||
VERSION = 2.0
|
||||
|
||||
ZLIBDIR=../zlib
|
||||
ENETDIR=../enet
|
||||
IRRNETDIR=1
|
||||
|
||||
ZLIBOBJ = $(ZLIBDIR)/adler32.o $(ZLIBDIR)/compress.o $(ZLIBDIR)/crc32.o $(ZLIBDIR)/deflate.o $(ZLIBDIR)/infback.o $(ZLIBDIR)/inffast.o $(ZLIBDIR)/inflate.o $(ZLIBDIR)/inftrees.o $(ZLIBDIR)/trees.o $(ZLIBDIR)/uncompr.o $(ZLIBDIR)/zutil.o
|
||||
#ENETOBJ = $(ENETDIR)/host.o $(ENETDIR)/list.o $(ENETDIR)/memory.o $(ENETDIR)/packet.o $(ENETDIR)/peer.o $(ENETDIR)/protocol.o $(ENETDIR)/unix.o $(ENETDIR)/win32.o
|
||||
ENETOBJ = $(ENETDIR)/host.o $(ENETDIR)/list.o $(ENETDIR)/callbacks.o $(ENETDIR)/packet.o $(ENETDIR)/peer.o $(ENETDIR)/protocol.o $(ENETDIR)/unix.o $(ENETDIR)/win32.o
|
||||
IRRNETOBJ = CNetManager.o SPacket.o
|
||||
LINKOBJ := $(IRRNETOBJ) $(ENETOBJ) $(ZLIBOBJ)
|
||||
|
||||
###############
|
||||
#Compiler flags
|
||||
#CXXINCS = -I../../include -I../$(ENETDIR)/include/ -Izlib
|
||||
CXXINCS = -I../include -I./$(ENETDIR)/include/ -I./NoIrrlicht/ -Izlib
|
||||
CPPFLAGS = $(CXXINCS)
|
||||
CXXFLAGS = -Wall -fexpensive-optimizations -O3
|
||||
|
||||
ifdef PROFILE
|
||||
CXXFLAGS += -pg
|
||||
endif
|
||||
CFLAGS := -fexpensive-optimizations -O3
|
||||
|
||||
#Linux specific options
|
||||
STATIC_LIB = libirrnet.a
|
||||
LIB_PATH = ../lib/$(STATIC_LIB)
|
||||
INSTALL_DIR = /usr/local/lib
|
||||
staticlib install: SYSTEM = Linux
|
||||
staticlib: LDFLAGS = --no-export-all-symbols --add-stdcall-alias
|
||||
####################
|
||||
all linux: staticlib
|
||||
|
||||
$(STATIC_LIB): $(LINKOBJ)
|
||||
$(AR) rs $@ $^
|
||||
|
||||
# Copies static lib into /lib/Linux
|
||||
staticlib: $(STATIC_LIB)
|
||||
mv $^ $(LIB_PATH)
|
||||
|
||||
# Create dependency files for automatic recompilation
|
||||
%.d:%.cpp
|
||||
$(CXX) $(CPPFLAGS) -MM -MF $@ $<
|
||||
|
||||
-include $(LINKOBJ:.o=.d)
|
||||
|
||||
clean:
|
||||
$(RM) $(LINKOBJ) $(SHARED_LIB).$(VERSION) $(STATIC_LIB) $(LINKOBJ:.o=.d)
|
||||
|
||||
#withirrlicht:
|
||||
#CXXINCS += -Iirrlicht/include -DCOMPILE_WITH_IRRLICHT
|
||||
|
||||
#all staticlib clean
|
||||
#
|
||||
#.PHONY: all staticlib clean
|
||||
#
|
|
@ -0,0 +1,51 @@
|
|||
IrrNetLite V2.0 - Lite Enet Framework
|
||||
-------------------------------------
|
||||
|
||||
irrNetLite is an lite enet wrapper with a clean C++ interface.
|
||||
Please look at Tutorial.cpp for a quick introduction to coding with irrNetLite.
|
||||
|
||||
switch(YourQuestions)
|
||||
{
|
||||
Why irrNetLite?:
|
||||
Enet is a portable, robust and reliable UDP implementation, but unfortunately
|
||||
it comes with an ugly C-style interface that can be rather difficult to integrate
|
||||
with a large scale application (Or to look at in general.). irrNetLite makes the
|
||||
experience a whole lot better by imploying OO-style interfaces for packet handling
|
||||
and connection callbacks and a sprinkle here and there of synctatic sugar (Operator
|
||||
overloading, etc). irrNetLite also implements some useful features not present in
|
||||
vanilla Enet (Namely compression and encryption), in the same easy to use manner.
|
||||
|
||||
Is there a connection to Irrlicht?:
|
||||
What are all these header files?:
|
||||
Do you have something against the std lib?:
irrNetLite V1.0 was originally based off irrNet. irrNet was a network library
|
||||
for integration of Enet and Irrlicht to create a persistant multi-user
|
||||
enviroment. irrNet was dependant on Irrlicht. irrNetLite however, has
|
||||
no dependancy whatsoever on Irrlicht being included or linked in. I do however
|
||||
like some of the Irrlicht typedefs and helper structures, so those are included
|
||||
amongst the header files, but by no means do you have to use them in your
|
||||
application. I do recommend using the typedefs, as it is important to maintain
|
||||
more precise typing (unsigned/signed) when sending data over a network due
|
||||
to deferring architecture defaults.
|
||||
}
|
||||
|
||||
LICENSE
|
||||
-----------
|
||||
|
||||
Copyright (C) 2008 Ahmed Hilali
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgement in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be clearly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
|
@ -0,0 +1,477 @@
|
|||
#include "SPacket.h"
|
||||
#include "zlib.h"
|
||||
#include "CEncryption.h"
|
||||
|
||||
uchar CEncryption::expKey[4 * Nb * (Nr + 1)] = {};
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace net
|
||||
{
|
||||
|
||||
SOutPacket::SOutPacket() {}
|
||||
|
||||
SOutPacket::SOutPacket(const c8* buff,const u32 buff_size)
|
||||
{
|
||||
this->buff.set_used(buff_size);
|
||||
memcpy(this->buff.pointer(),buff,buff_size);
|
||||
}
|
||||
|
||||
void SOutPacket::clearData()
|
||||
{
|
||||
buff.clear();
|
||||
}
|
||||
|
||||
c8* SOutPacket::getData()
|
||||
{
|
||||
return (c8*)buff.pointer();
|
||||
}
|
||||
|
||||
const c8* SOutPacket::getConstData()
|
||||
{
|
||||
return (const c8*)buff.const_pointer();
|
||||
}
|
||||
|
||||
u32 SOutPacket::getSize()
|
||||
{
|
||||
return buff.size();
|
||||
}
|
||||
|
||||
void SOutPacket::enlargeBuffer(const u32 size)
|
||||
{
|
||||
const u32 newSize = buff.size() + size;
|
||||
if(buff.allocated_size() < newSize)
|
||||
buff.reallocate(newSize * 2);
|
||||
|
||||
buff.set_used(newSize);
|
||||
}
|
||||
|
||||
SOutPacket& SOutPacket::operator << (const c8 data)
|
||||
{
|
||||
buff.push_back(data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SOutPacket& SOutPacket::operator << (const u16 data)
|
||||
{
|
||||
enlargeBuffer(2);
|
||||
memcpy(buff.pointer() + buff.size() - 2, &data, 2);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SOutPacket& SOutPacket::operator << (const u32 data)
|
||||
{
|
||||
enlargeBuffer(4);
|
||||
memcpy(buff.pointer() + buff.size() - 4, &data, 4);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SOutPacket& SOutPacket::operator << (const u8 data)
|
||||
{
|
||||
buff.push_back(data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SOutPacket& SOutPacket::operator << (const s16 data)
|
||||
{
|
||||
enlargeBuffer(2);
|
||||
memcpy(buff.pointer() + buff.size() - 2, &data, 2);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SOutPacket& SOutPacket::operator << (const s32 data)
|
||||
{
|
||||
enlargeBuffer(4);
|
||||
memcpy(buff.pointer() + buff.size() - 4, &data, 4);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SOutPacket& SOutPacket::operator << (const f32 data)
|
||||
{
|
||||
enlargeBuffer(4);
|
||||
memcpy(buff.pointer() + buff.size() - 4, &data, 4);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SOutPacket& SOutPacket::operator << (const f64 data)
|
||||
{
|
||||
enlargeBuffer(8);
|
||||
memcpy(buff.pointer() + buff.size() - 8, &data, 8);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SOutPacket& SOutPacket::operator << (const core::vector3df& data)
|
||||
{
|
||||
enlargeBuffer(12);
|
||||
memcpy(buff.pointer() + buff.size() - 12, &data.X, 12);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SOutPacket& SOutPacket::operator << (const c8* string)
|
||||
{
|
||||
u16 tmp = (u16)strlen(string);
|
||||
|
||||
enlargeBuffer(2);
|
||||
memcpy(buff.pointer() + buff.size() - 2, &tmp, 2);
|
||||
|
||||
enlargeBuffer(tmp);
|
||||
memcpy(buff.pointer() + buff.size() - tmp, string, tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SOutPacket& SOutPacket::operator << (const core::stringc& string)
|
||||
{
|
||||
u16 tmp = string.size();
|
||||
|
||||
enlargeBuffer(2);
|
||||
memcpy(buff.pointer() + buff.size() - 2, &tmp, 2);
|
||||
|
||||
enlargeBuffer(tmp);
|
||||
memcpy(buff.pointer() + buff.size() - tmp, &string[0], tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SOutPacket& SOutPacket::operator << (const std::string& string)
|
||||
{
|
||||
u16 tmp = (u16)string.size();
|
||||
|
||||
enlargeBuffer(2);
|
||||
memcpy(buff.pointer() + buff.size() - 2, &tmp, 2);
|
||||
|
||||
enlargeBuffer(tmp);
|
||||
memcpy(buff.pointer() + buff.size() - tmp, &string[0], tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SOutPacket& SOutPacket::operator << (const core::stringw& string)
|
||||
{
|
||||
const u16 tmp = string.size();
|
||||
|
||||
enlargeBuffer(2);
|
||||
memcpy(buff.pointer() + buff.size() - 2, &tmp, 2);
|
||||
|
||||
enlargeBuffer(1);
|
||||
const u8 wCharSize = sizeof(wchar_t);
|
||||
memcpy(buff.pointer() + buff.size() - 1, &wCharSize, 1);
|
||||
|
||||
const u32 wcharByteSize = (tmp * sizeof(wchar_t));
|
||||
enlargeBuffer(wcharByteSize);
|
||||
memcpy(buff.pointer() + buff.size() - wcharByteSize, &string[0], wcharByteSize);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SOutPacket& SOutPacket::operator << (const SOutPacket& other)
|
||||
{
|
||||
enlargeBuffer(other.buff.size());
|
||||
memcpy(buff.pointer() + buff.size() - other.buff.size(), other.buff.const_pointer(), other.buff.size());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SOutPacket::compressPacket()
|
||||
{
|
||||
const u32 compBound = compressBound(buff.size()) + 4;
|
||||
core::array<c8> newBuff(compBound);
|
||||
|
||||
const u32 currSize = buff.size();
|
||||
memcpy(newBuff.pointer(), &currSize, 4);
|
||||
|
||||
uLongf destLen = compBound;
|
||||
compress((Bytef*)newBuff.pointer() + 4, &destLen, (Bytef*)buff.pointer(), buff.size());
|
||||
newBuff.set_used(destLen + 4);
|
||||
|
||||
buff = newBuff;
|
||||
}
|
||||
|
||||
void SOutPacket::deCompressPacket()
|
||||
{
|
||||
u32 newSize = 0;
|
||||
memcpy((void*)&newSize, buff.pointer(), 4);
|
||||
|
||||
core::array<c8> newBuff;
|
||||
newBuff.set_used(newSize);
|
||||
|
||||
uLongf destLen = newSize;
|
||||
uncompress((Bytef*)newBuff.pointer(), &destLen, (Bytef*)buff.pointer() + 4, buff.size() - 4);
|
||||
newBuff.set_used(destLen);
|
||||
|
||||
buff = newBuff;
|
||||
}
|
||||
|
||||
void SOutPacket::encryptPacket(const c8 key[16])
|
||||
{
|
||||
CEncryption::SetEncryptionKey((u8*)&key[0]);
|
||||
core::array<c8> tmpbuff;
|
||||
const u32 newSize = buff.size() + (16 - (buff.size() % 16));
|
||||
tmpbuff.set_used(newSize);
|
||||
buff.set_used(newSize);
|
||||
|
||||
for(u32 i = 0;i < newSize;i+=16)
|
||||
CEncryption::Encrypt((u8*)buff.pointer() + i, (u8*)tmpbuff.pointer() + i);
|
||||
|
||||
buff = tmpbuff;
|
||||
}
|
||||
|
||||
void SOutPacket::decryptPacket(const c8 key[16])
|
||||
{
|
||||
CEncryption::SetEncryptionKey((u8*)&key[0]);
|
||||
const u32 newSize = buff.size();
|
||||
core::array<c8> tmpbuff;
|
||||
tmpbuff.set_used(newSize);
|
||||
|
||||
for(u32 i = 0;i < newSize;i+=16)
|
||||
CEncryption::Decrypt((u8*)buff.pointer() + i, (u8*)tmpbuff.pointer() + i);
|
||||
|
||||
buff = tmpbuff;
|
||||
}
|
||||
|
||||
SInPacket::SInPacket(const c8* buff, const u32 size) : pos(0), playerid(0)
|
||||
{
|
||||
SInPacket::buff.set_used(size);
|
||||
memcpy(SInPacket::buff.pointer(), buff, size);
|
||||
}
|
||||
|
||||
|
||||
void SInPacket::setNewData(const c8* buffer, const u32 size)
|
||||
{
|
||||
buff.set_used(size);
|
||||
memcpy(buff.pointer(), buffer, size);
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
void SInPacket::setPlayerId(u16 playernumber)
|
||||
{
|
||||
playerid = playernumber;
|
||||
}
|
||||
|
||||
void SInPacket::operator >> (c8 &data)
|
||||
{
|
||||
memcpy(&data,getData()+pos,1);
|
||||
pos++;
|
||||
}
|
||||
|
||||
void SInPacket::operator >> (f32 &data)
|
||||
{
|
||||
memcpy(&data,getData()+pos,4);
|
||||
pos+=4;
|
||||
}
|
||||
|
||||
void SInPacket::operator >> (f64 &data)
|
||||
{
|
||||
memcpy(&data,getData()+pos,8);
|
||||
pos+=8;
|
||||
}
|
||||
|
||||
void SInPacket::operator >> (u16 &data)
|
||||
{
|
||||
memcpy(&data,getData()+pos,2);
|
||||
pos+=2;
|
||||
}
|
||||
|
||||
void SInPacket::operator >> (u32 &data)
|
||||
{
|
||||
memcpy(&data,getData()+pos,4);
|
||||
pos+=4;
|
||||
}
|
||||
|
||||
void SInPacket::operator >> (u8 &data)
|
||||
{
|
||||
memcpy(&data,getData()+pos,1);
|
||||
pos++;
|
||||
}
|
||||
|
||||
void SInPacket::operator >> (s16 &data)
|
||||
{
|
||||
memcpy(&data,getData()+pos,2);
|
||||
pos+=2;
|
||||
}
|
||||
|
||||
void SInPacket::operator >> (s32 &data)
|
||||
{
|
||||
memcpy(&data,getData()+pos,4);
|
||||
pos+=4;
|
||||
}
|
||||
|
||||
void SInPacket::operator >> (core::vector3df &data)
|
||||
{
|
||||
memcpy(&data.X,getData()+pos,12);
|
||||
pos+=12;
|
||||
}
|
||||
|
||||
void SInPacket::operator >> (char *string)
|
||||
{
|
||||
u16 sz;
|
||||
memcpy(&sz,getData()+pos,2);
|
||||
pos+=2;
|
||||
|
||||
memcpy(string,getData()+pos,sz);
|
||||
pos += sz;
|
||||
|
||||
string[sz] = '\0';
|
||||
}
|
||||
|
||||
void SInPacket::operator >> (core::stringc& string)
|
||||
{
|
||||
u16 sz;
|
||||
memcpy(&sz, getData() + pos, 2);
|
||||
pos+=2;
|
||||
|
||||
char* tempBuff = new char[sz + 1];
|
||||
memcpy(tempBuff, getData() + pos, sz);
|
||||
tempBuff[sz] = '\0';
|
||||
string = tempBuff;
|
||||
|
||||
delete [] tempBuff;
|
||||
|
||||
pos += sz;
|
||||
}
|
||||
|
||||
void SInPacket::operator >> (std::string& string)
|
||||
{
|
||||
u16 sz;
|
||||
memcpy(&sz, getData() + pos, 2);
|
||||
pos+=2;
|
||||
|
||||
char* tempBuff = new char[sz + 1];
|
||||
memcpy(tempBuff, getData() + pos, sz);
|
||||
tempBuff[sz] = '\0';
|
||||
string = tempBuff;
|
||||
|
||||
delete [] tempBuff;
|
||||
|
||||
pos += sz;
|
||||
}
|
||||
|
||||
void SInPacket::operator >> (core::stringw& string)
|
||||
{
|
||||
u16 sz;
|
||||
memcpy(&sz,getData()+pos,2);
|
||||
pos+=2;
|
||||
|
||||
u8 wCharSize;
|
||||
memcpy(&wCharSize,getData()+pos,1);
|
||||
pos+=1;
|
||||
|
||||
wchar_t* tempBuff = new wchar_t[sz + 1];
|
||||
const u32 wcharByteSize = (sz * sizeof(wchar_t));
|
||||
|
||||
if(wCharSize != sizeof(wchar_t))
|
||||
{
|
||||
if(wCharSize > sizeof(wchar_t))
|
||||
{
|
||||
for(u32 i = 0;i < sz;i++)
|
||||
{
|
||||
tempBuff[i] = 0;
|
||||
memcpy(&tempBuff[i],getData()+pos,sizeof(wchar_t));
|
||||
|
||||
pos += wCharSize;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(u32 i = 0;i < sz;i++)
|
||||
{
|
||||
tempBuff[i] = 0;
|
||||
memcpy(&tempBuff[i],getData()+pos,wCharSize);
|
||||
|
||||
pos += wCharSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(tempBuff, getData() + pos, wcharByteSize);
|
||||
}
|
||||
|
||||
tempBuff[sz] = '\0';
|
||||
string = tempBuff;
|
||||
|
||||
delete [] tempBuff;
|
||||
|
||||
pos += wcharByteSize;
|
||||
}
|
||||
|
||||
u16 SInPacket::getPlayerId() const
|
||||
{
|
||||
return playerid;
|
||||
}
|
||||
|
||||
void SInPacket::resetPos()
|
||||
{
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
c8* SInPacket::getData()
|
||||
{
|
||||
return (c8*)buff.pointer();
|
||||
}
|
||||
|
||||
const c8* SInPacket::getConstData()
|
||||
{
|
||||
return (const c8*)buff.const_pointer();
|
||||
}
|
||||
|
||||
void SInPacket::compressPacket()
|
||||
{
|
||||
const u32 compBound = compressBound(buff.size()) + 4;
|
||||
core::array<c8> newBuff(compBound);
|
||||
|
||||
const u32 currSize = buff.size();
|
||||
memcpy(newBuff.pointer(), &currSize, 4);
|
||||
|
||||
uLongf destLen = compBound;
|
||||
compress((Bytef*)newBuff.pointer() + 4, &destLen, (Bytef*)buff.pointer(), buff.size());
|
||||
newBuff.set_used(destLen + 4);
|
||||
|
||||
buff = newBuff;
|
||||
}
|
||||
|
||||
void SInPacket::deCompressPacket()
|
||||
{
|
||||
u32 newSize = 0;
|
||||
memcpy((void*)&newSize, buff.pointer(), 4);
|
||||
|
||||
core::array<c8> newBuff;
|
||||
newBuff.set_used(newSize);
|
||||
|
||||
uLongf destLen = newSize;
|
||||
uncompress((Bytef*)newBuff.pointer(), &destLen, (Bytef*)buff.pointer() + 4, buff.size() - 4);
|
||||
newBuff.set_used(destLen);
|
||||
|
||||
buff = newBuff;
|
||||
}
|
||||
|
||||
void SInPacket::encryptPacket(const c8 key[16])
|
||||
{
|
||||
CEncryption::SetEncryptionKey((u8*)&key[0]);
|
||||
core::array<c8> tmpbuff;
|
||||
const u32 newSize = buff.size() + (16 - (buff.size() % 16));
|
||||
tmpbuff.set_used(newSize);
|
||||
buff.set_used(newSize);
|
||||
|
||||
for(u32 i = 0;i < newSize;i+=16)
|
||||
CEncryption::Encrypt((u8*)buff.pointer() + i, (u8*)tmpbuff.pointer() + i);
|
||||
|
||||
buff = tmpbuff;
|
||||
}
|
||||
|
||||
void SInPacket::decryptPacket(const c8 key[16])
|
||||
{
|
||||
CEncryption::SetEncryptionKey((u8*)&key[0]);
|
||||
const u32 newSize = buff.size();
|
||||
core::array<c8> tmpbuff;
|
||||
tmpbuff.set_used(newSize);
|
||||
|
||||
for(u32 i = 0;i < newSize;i+=16)
|
||||
CEncryption::Decrypt((u8*)buff.pointer() + i, (u8*)tmpbuff.pointer() + i);
|
||||
|
||||
buff = tmpbuff;
|
||||
}
|
||||
|
||||
u32 SInPacket::getSize()
|
||||
{
|
||||
return buff.size();
|
||||
}
|
||||
|
||||
} // Close Net Namespace
|
||||
} // Close Irr namespace
|
|
@ -0,0 +1,6 @@
|
|||
SPacket.o: SPacket.cpp ../include/SPacket.h \
|
||||
../include/NoIrrlicht/NoIrrlicht.h ../include/NoIrrlicht/irrTypes.h \
|
||||
../include/NoIrrlicht/irrArray.h ../include/NoIrrlicht/heapsort.h \
|
||||
../include/NoIrrlicht/irrAllocator.h ../include/NoIrrlicht/irrString.h \
|
||||
../include/NoIrrlicht/irrMath.h ../include/NoIrrlicht/IrrCompileConfig.h \
|
||||
../include/NoIrrlicht/vector3d.h ../include/CEncryption.h
|
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
Subproject commit cacf7f1d4e3d44d871b605da3b647f07d718623f
|
Loading…
Reference in New Issue