Convert space indentations to tabs

This commit is contained in:
Tomoaki Kawada 2016-11-20 19:13:00 +09:00
parent 29c42d950b
commit 18f3e81fd1
15 changed files with 2256 additions and 2256 deletions

View File

@ -1,21 +1,21 @@
/*
Copyright (c) 2013 yvt
This file is part of OpenSpades.
OpenSpades is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenSpades is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ALFuncs.h"
@ -168,33 +168,33 @@ namespace al{
static void *GPA(const char *str)
{
if(!alLibrary){
auto paths = spades::Split(s_alDriver, ";");
std::string errors;
for (const std::string &path: paths) {
auto trimmedPath = spades::TrimSpaces(path);
try {
alLibrary = new spades::DynamicLibrary(trimmedPath.c_str());
if (alLibrary) {
SPLog("'%s' loaded", trimmedPath.c_str());
break;
}
} catch (const std::exception &ex) {
errors += trimmedPath;
errors += ":\n";
errors += ex.what();
}
}
if (!alLibrary) {
SPRaise("Failed to load a OpenAL driver.\n%s", errors.c_str());
}
auto paths = spades::Split(s_alDriver, ";");
std::string errors;
for (const std::string &path: paths) {
auto trimmedPath = spades::TrimSpaces(path);
try {
alLibrary = new spades::DynamicLibrary(trimmedPath.c_str());
if (alLibrary) {
SPLog("'%s' loaded", trimmedPath.c_str());
break;
}
} catch (const std::exception &ex) {
errors += trimmedPath;
errors += ":\n";
errors += ex.what();
}
}
if (!alLibrary) {
SPRaise("Failed to load a OpenAL driver.\n%s", errors.c_str());
}
}
if(qalGetProcAddress){
void *v = qalGetProcAddress(str);
if(v)
return v;
}
return alLibrary->GetSymbol(str);
}
@ -204,7 +204,7 @@ namespace al{
void InitEAX(void){
ALCdevice *pDevice = NULL;
ALCcontext *pContext = NULL;
pContext = qalcGetCurrentContext();
pDevice = qalcGetContextsDevice(pContext);
@ -246,9 +246,9 @@ namespace al{
SPRaise("Extension not found: '%s'",
ALC_EXT_EFX_NAME);
}
}
void Link(void) {
SPLog("Linking with OpenAL library.");
L(alEnable);
@ -306,7 +306,7 @@ namespace al{
L(alDopplerFactor);
L(alDopplerVelocity);
L(alDistanceModel);
L(alcCreateContext);
L(alcMakeContextCurrent);
L(alcProcessContext);
@ -322,9 +322,9 @@ namespace al{
L(alcGetEnumValue);
L(alcGetString);
L(alcGetIntegerv);
}
const char *DescribeError(ALenum e){
switch(e){
case AL_NO_ERROR:
@ -343,7 +343,7 @@ namespace al{
return "Unknown error";
}
}
void CheckError(void){
ALenum e;
e = qalGetError();
@ -354,7 +354,7 @@ namespace al{
SPLog("OpenAL error %d: %s", (int)e, DescribeError(e));
}
}
void CheckError(const char *source, const char *fun, int line){
ALenum e;
e = qalGetError();

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +1,22 @@
/*
Copyright (c) 2013 yvt
based on code of pysnip (c) Mathias Kaerlev 2011-2012.
This file is part of OpenSpades.
OpenSpades is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenSpades is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Client.h"
@ -90,18 +90,18 @@ DEFINE_SPADES_SETTING(cg_keyAutoFocus, "MiddleMouseButton");
namespace spades {
namespace client {
bool Client::WantsToBeClosed() {
return readyToClose;
}
bool FirstPersonSpectate = false;
void Client::Closing() {
SPADES_MARK_FUNCTION();
}
bool Client::NeedsAbsoluteMouseCoordinate() {
SPADES_MARK_FUNCTION();
if(scriptedUI->NeedsInput()) {
@ -116,20 +116,20 @@ namespace spades {
}
return false;
}
void Client::MouseEvent(float x, float y) {
SPADES_MARK_FUNCTION();
if(scriptedUI->NeedsInput()) {
scriptedUI->MouseEvent(x, y);
return;
}
if(IsLimboViewActive()){
limbo->MouseEvent(x, y);
return;
}
if(IsFollowing()){
SPAssert(world != nullptr);
/*
@ -140,11 +140,11 @@ namespace spades {
x = -x; y = -y;
}
*/
x = -x;
if (!cg_invertMouseY)
y = -y;
followYaw -= x * 0.003f;
followPitch -= y * 0.003f;
if(followPitch < -M_PI*.45f) followPitch = -static_cast<float>(M_PI)*.45f;
@ -156,7 +156,7 @@ namespace spades {
if(p->IsAlive()){
x /= GetAimDownZoomScale();
y /= GetAimDownZoomScale();
float rad = x * x + y * y;
if(rad > 0.f) {
if((float)cg_mouseExpPower < 0.001f ||
@ -168,40 +168,40 @@ namespace spades {
factor *= factor;
rad /= factor;
rad = powf(rad, (float)cg_mouseExpPower * 0.5f - 0.5f);
// shouldn't happen...
if(isnan(rad)) rad = 1.f;
x *= rad;
y *= rad;
}
if(aimDownState > 0.f) {
float scale = cg_zoomedMouseSensScale;
scale = powf(scale, aimDownState);
x *= scale;
y *= scale;
}
x *= (float)cg_mouseSensitivity;
y *= (float)cg_mouseSensitivity;
if(cg_invertMouseY)
y = -y;
p->Turn(x * 0.003f, y * 0.003f);
}
}
}
void Client::WheelEvent(float x, float y) {
SPADES_MARK_FUNCTION();
if(scriptedUI->NeedsInput()) {
scriptedUI->WheelEvent(x, y);
return;
}
if(y > .5f) {
KeyEvent("WheelDown", true);
KeyEvent("WheelDown", false);
@ -210,37 +210,37 @@ namespace spades {
KeyEvent("WheelUp", false);
}
}
void Client::TextInputEvent(const std::string &ch){
SPADES_MARK_FUNCTION();
if (scriptedUI->NeedsInput() && !scriptedUI->isIgnored(ch)) {
scriptedUI->TextInputEvent(ch);
return;
}
// we don't get "/" here anymore
}
void Client::TextEditingEvent(const std::string &ch,
int start, int len) {
SPADES_MARK_FUNCTION();
if (scriptedUI->NeedsInput() && !scriptedUI->isIgnored(ch)) {
scriptedUI->TextEditingEvent(ch, start, len);
return;
}
}
bool Client::AcceptsTextInput() {
SPADES_MARK_FUNCTION();
if(scriptedUI->NeedsInput()) {
return scriptedUI->AcceptsTextInput();
}
return false;
}
AABB2 Client::GetTextInputRect() {
SPADES_MARK_FUNCTION();
if(scriptedUI->NeedsInput()) {
@ -248,7 +248,7 @@ namespace spades {
}
return AABB2();
}
static bool CheckKey(const std::string& cfg,
const std::string& input) {
if(cfg.empty())
@ -272,10 +272,10 @@ namespace spades {
}
return false;
}
void Client::KeyEvent(const std::string& name, bool down){
SPADES_MARK_FUNCTION();
if(scriptedUI->NeedsInput()) {
if(!scriptedUI->isIgnored(name)) {
scriptedUI->KeyEvent(name, down);
@ -286,7 +286,7 @@ namespace spades {
}
return;
}
if(name == "Escape"){
if(down){
if(inGameLimbo){
@ -332,13 +332,13 @@ namespace spades {
}
if(world->GetLocalPlayer()){
Player *p = world->GetLocalPlayer();
if(p->IsAlive() && p->GetTool() == Player::ToolBlock && down) {
if(paletteView->KeyInput(name)){
return;
}
}
if(cg_debugCorpse){
if(name == "p" && down){
Corpse *corp;
@ -346,7 +346,7 @@ namespace spades {
corp = new Corpse(renderer, map, victim);
corp->AddImpulse(victim->GetFront() * 32.f);
corpses.emplace_back(corp);
if(corpses.size() > corpseHardLimit){
corpses.pop_front();
}else if(corpses.size() > corpseSoftLimit){
@ -412,14 +412,14 @@ namespace spades {
(!w->IsReloading()) &&
world->GetLocalPlayer()->GetTool() == Player::ToolWeapon){
if(world->GetLocalPlayer()->IsToolWeapon()){
if(weapInput.secondary) {
// if we send WeaponInput after sending Reload,
// server might cancel the reload.
// https://github.com/infogulch/pyspades/blob/895879ed14ddee47bb278a77be86d62c7580f8b7/pyspades/server.py#343
hasDelayedReload = true;
weapInput.secondary = false;
return;
}
if(weapInput.secondary) {
// if we send WeaponInput after sending Reload,
// server might cancel the reload.
// https://github.com/infogulch/pyspades/blob/895879ed14ddee47bb278a77be86d62c7580f8b7/pyspades/server.py#343
hasDelayedReload = true;
weapInput.secondary = false;
return;
}
}
world->GetLocalPlayer()->Reload();
net->SendReload();
@ -590,8 +590,8 @@ namespace spades {
}
}
}
}
}

View File

@ -1,22 +1,22 @@
/*
Copyright (c) 2013 yvt
based on code of pysnip (c) Mathias Kaerlev 2011-2012.
This file is part of OpenSpades.
OpenSpades is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenSpades is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Client.h"
@ -60,28 +60,28 @@ DEFINE_SPADES_SETTING(cg_autoFocusSpeed, "0.4");
namespace spades {
namespace client {
#pragma mark - Local Entities / Effects
void Client::RemoveAllCorpses(){
SPADES_MARK_FUNCTION();
corpses.clear();
lastMyCorpse = nullptr;
}
void Client::RemoveAllLocalEntities(){
SPADES_MARK_FUNCTION();
localEntities.clear();
}
void Client::RemoveInvisibleCorpses(){
SPADES_MARK_FUNCTION();
decltype(corpses)::iterator it;
std::vector<decltype(it)> its;
int cnt = (int)corpses.size() - corpseSoftLimit;
@ -96,13 +96,13 @@ namespace spades {
}
cnt--;
}
for(size_t i = 0; i < its.size(); i++)
corpses.erase(its[i]);
}
Player *Client::HotTrackedPlayer( hitTag_t* hitFlag ){
if(!world)
return nullptr;
@ -114,10 +114,10 @@ namespace spades {
Vector3 origin = p->GetEye();
Vector3 dir = p->GetFront();
World::WeaponRayCastResult result = world->WeaponRayCast(origin, dir, p);
if(result.hit == false || result.player == nullptr)
return nullptr;
// don't hot track enemies (non-spectator only)
if(result.player->GetTeamId() != p->GetTeamId() &&
p->GetTeamId() < 2)
@ -127,27 +127,27 @@ namespace spades {
}
return result.player;
}
bool Client::IsMuted() {
// prevent to play loud sound at connection
// caused by saved packets
return time < worldSetTime + .05f;
}
void Client::Bleed(spades::Vector3 v){
SPADES_MARK_FUNCTION();
if(!cg_blood)
return;
// distance cull
if((v - lastSceneDef.viewOrigin).GetPoweredLength() >
150.f * 150.f)
return;
if ((int)cg_particles < 1)
return;
if ((int)cg_particles < 1)
return;
Handle<IImage> img = renderer->RegisterImage("Gfx/White.tga");
Vector4 color = {0.5f, 0.02f, 0.04f, 1.f};
for(int i = 0; i < 10; i++){
@ -162,11 +162,11 @@ namespace spades {
ent->SetRadius(0.1f + GetRandom()*GetRandom()*0.2f);
ent->SetLifeTime(3.f, 0.f, 1.f);
localEntities.emplace_back(ent);
}
if((int) cg_particles < 2)
return;
}
if((int) cg_particles < 2)
return;
color = MakeVector4(.7f, .35f, .37f, .6f);
for(int i = 0; i < 2; i++){
ParticleSpriteEntity *ent =
@ -184,7 +184,7 @@ namespace spades {
ent->SetLifeTime(.20f + GetRandom() * .2f, 0.06f, .20f);
localEntities.emplace_back(ent);
}
color.w *= .1f;
for(int i = 0; i < 1; i++){
ParticleSpriteEntity *ent =
@ -203,20 +203,20 @@ namespace spades {
localEntities.emplace_back(ent);
}
}
void Client::EmitBlockFragments(Vector3 origin,
IntVector3 c){
SPADES_MARK_FUNCTION();
// distance cull
float distPowered = (origin - lastSceneDef.viewOrigin).GetPoweredLength();
if(distPowered >
150.f * 150.f)
return;
if ((int)cg_particles < 1)
return;
if ((int)cg_particles < 1)
return;
Handle<IImage> img = renderer->RegisterImage("Gfx/White.tga");
Vector4 color = {c.x / 255.f,
c.y / 255.f, c.z / 255.f, 1.f};
@ -235,10 +235,10 @@ namespace spades {
ent->SetBlockHitAction(ParticleSpriteEntity::BounceWeak);
localEntities.emplace_back(ent);
}
if ((int)cg_particles < 2)
return;
if ((int)cg_particles < 2)
return;
if(distPowered <
32.f * 32.f){
for(int i = 0; i < 16; i++){
@ -257,7 +257,7 @@ namespace spades {
localEntities.emplace_back(ent);
}
}
color += (MakeVector4(1, 1, 1, 1) - color) * .2f;
color.w *= .2f;
for(int i = 0; i < 2; i++){
@ -275,23 +275,23 @@ namespace spades {
ent->SetBlockHitAction(ParticleSpriteEntity::Ignore);
localEntities.emplace_back(ent);
}
}
void Client::EmitBlockDestroyFragments(IntVector3 blk,
IntVector3 c){
SPADES_MARK_FUNCTION();
Vector3 origin = {blk.x + .5f, blk.y + .5f, blk.z + .5f};
// distance cull
if((origin - lastSceneDef.viewOrigin).GetPoweredLength() >
150.f * 150.f)
return;
if ((int)cg_particles < 1)
return;
if ((int)cg_particles < 1)
return;
Handle<IImage> img = renderer->RegisterImage("Gfx/White.tga");
Vector4 color = {c.x / 255.f,
c.y / 255.f, c.z / 255.f, 1.f};
@ -310,7 +310,7 @@ namespace spades {
localEntities.emplace_back(ent);
}
}
void Client::MuzzleFire(spades::Vector3 origin,
spades::Vector3 dir,
bool local) {
@ -320,14 +320,14 @@ namespace spades {
l.type = DynamicLightTypePoint;
l.color = MakeVector3(3.f, 1.6f, 0.5f);
flashDlights.push_back(l);
if ((int)cg_particles < 1)
return;
if ((int)cg_particles < 1)
return;
Vector4 color;
Vector3 velBias = {0, 0, -0.5f};
color = MakeVector4( .8f, .8f, .8f, .3f);
// rapid smoke
for(int i = 0; i < 2; i++){
ParticleSpriteEntity *ent =
@ -346,7 +346,7 @@ namespace spades {
localEntities.emplace_back(ent);
}
}
void Client::GrenadeExplosion(spades::Vector3 origin){
float dist = (origin - lastSceneDef.viewOrigin).GetLength();
if(dist > 170.f)
@ -354,7 +354,7 @@ namespace spades {
grenadeVibration += 2.f / (dist + 5.f);
if(grenadeVibration > 1.f)
grenadeVibration = 1.f;
DynamicLightParam l;
l.origin = origin;
l.radius = 16.f;
@ -362,10 +362,10 @@ namespace spades {
l.color = MakeVector3(3.f, 1.6f, 0.5f);
l.useLensFlare = true;
flashDlights.push_back(l);
if ((int)cg_particles < 1)
return;
if ((int)cg_particles < 1)
return;
Vector3 velBias = {0,0,0};
if(!map->ClipBox(origin.x, origin.y, origin.z)){
if(map->ClipBox(origin.x + 1.f, origin.y, origin.z)){
@ -387,7 +387,7 @@ namespace spades {
velBias.z += 1.f;
}
}
Vector4 color;
color = MakeVector4( .6f, .6f, .6f, 1.f);
// rapid smoke
@ -407,7 +407,7 @@ namespace spades {
ent->SetLifeTime(1.8f + GetRandom()*0.1f, 0.f, .20f);
localEntities.emplace_back(ent);
}
// slow smoke
color.w = .25f;
for(int i = 0; i < 8; i++){
@ -422,21 +422,21 @@ namespace spades {
ent->SetRadius(1.5f + GetRandom()*GetRandom()*0.8f,
0.2f);
ent->SetBlockHitAction(ParticleSpriteEntity::Ignore);
switch ((int) cg_particles) {
case 1:
ent->SetLifeTime(0.8f + GetRandom() * 1.f, 0.1f, 8.f);
break;
case 2:
ent->SetLifeTime(1.5f + GetRandom() * 2.f, 0.1f, 8.f);
break;
case 3:
default:
ent->SetLifeTime(2.f + GetRandom() * 5.f, 0.1f, 8.f);
break;
}
switch ((int) cg_particles) {
case 1:
ent->SetLifeTime(0.8f + GetRandom() * 1.f, 0.1f, 8.f);
break;
case 2:
ent->SetLifeTime(1.5f + GetRandom() * 2.f, 0.1f, 8.f);
break;
case 3:
default:
ent->SetLifeTime(2.f + GetRandom() * 5.f, 0.1f, 8.f);
break;
}
localEntities.emplace_back(ent);
}
// fragments
Handle<IImage> img = renderer->RegisterImage("Gfx/White.tga");
color = MakeVector4(0.01, 0.03, 0, 1.f);
@ -457,7 +457,7 @@ namespace spades {
ent->SetBlockHitAction(ParticleSpriteEntity::BounceWeak);
localEntities.emplace_back(ent);
}
// fire smoke
color= MakeVector4(1.f, .7f, .4f, .2f) * 5.f;
for(int i = 0; i < 4; i++){
@ -478,7 +478,7 @@ namespace spades {
localEntities.emplace_back(ent);
}
}
void Client::GrenadeExplosionUnderwater(spades::Vector3 origin){
float dist = (origin - lastSceneDef.viewOrigin).GetLength();
if(dist > 170.f)
@ -486,18 +486,18 @@ namespace spades {
grenadeVibration += 1.5f / (dist + 5.f);
if(grenadeVibration > 1.f)
grenadeVibration = 1.f;
if((int) cg_particles < 1)
return;
if((int) cg_particles < 1)
return;
Vector3 velBias = {0,0,0};
Vector4 color;
color = MakeVector4( .95f, .95f, .95f, .6f);
// water1
Handle<IImage> img = renderer->RegisterImage("Textures/WaterExpl.png");
if((int) cg_particles < 2)
color.w = .3f;
Handle<IImage> img = renderer->RegisterImage("Textures/WaterExpl.png");
if((int) cg_particles < 2)
color.w = .3f;
for(int i = 0; i < 7; i++){
ParticleSpriteEntity *ent =
new ParticleSpriteEntity(this, img, color);
@ -513,12 +513,12 @@ namespace spades {
ent->SetLifeTime(3.f + GetRandom()*0.3f, 0.f, .60f);
localEntities.emplace_back(ent);
}
// water2
img = renderer->RegisterImage("Textures/Fluid.png");
color.w = .9f;
if((int) cg_particles < 2)
color.w = .4f;
color.w = .4f;
for(int i = 0; i < 16; i++){
ParticleSpriteEntity *ent =
new ParticleSpriteEntity(this, img, color);
@ -534,11 +534,11 @@ namespace spades {
ent->SetLifeTime(3.f + GetRandom()*0.3f, .7f, .60f);
localEntities.emplace_back(ent);
}
// slow smoke
color.w = .4f;
if((int) cg_particles < 2)
color.w = .2f;
color.w = .4f;
if((int) cg_particles < 2)
color.w = .2f;
for(int i = 0; i < 8; i++){
ParticleSpriteEntity *ent =
new SmokeSpriteEntity(this, color, 20.f);
@ -551,20 +551,20 @@ namespace spades {
ent->SetRadius(1.4f + GetRandom()*GetRandom()*0.8f,
0.2f);
ent->SetBlockHitAction(ParticleSpriteEntity::Ignore);
switch ((int)cg_particles) {
case 1:
ent->SetLifeTime(3.f + GetRandom() * 5.f, 0.1f, 8.f);
break;
case 2:
case 3:
default:
ent->SetLifeTime(6.f + GetRandom() * 5.f, 0.1f, 8.f);
break;
}
switch ((int)cg_particles) {
case 1:
ent->SetLifeTime(3.f + GetRandom() * 5.f, 0.1f, 8.f);
break;
case 2:
case 3:
default:
ent->SetLifeTime(6.f + GetRandom() * 5.f, 0.1f, 8.f);
break;
}
localEntities.emplace_back(ent);
}
// fragments
img = renderer->RegisterImage("Gfx/White.tga");
color = MakeVector4(1,1,1, 0.7f);
@ -586,22 +586,22 @@ namespace spades {
ent->SetBlockHitAction(ParticleSpriteEntity::Delete);
localEntities.emplace_back(ent);
}
// TODO: wave?
}
void Client::BulletHitWaterSurface(spades::Vector3 origin){
float dist = (origin - lastSceneDef.viewOrigin).GetLength();
if(dist > 150.f)
return;
if(!cg_waterImpact)
return;
if((int) cg_particles < 1)
return;
if((int) cg_particles < 1)
return;
Vector4 color;
color = MakeVector4( .95f, .95f, .95f, .3f);
// water1
@ -622,7 +622,7 @@ namespace spades {
ent->SetLifeTime(3.f + GetRandom()*0.3f, 0.1f, .60f);
localEntities.emplace_back(ent);
}
// water2
img = renderer->RegisterImage("Textures/Fluid.png");
color.w = .9f;
@ -642,8 +642,8 @@ namespace spades {
ent->SetLifeTime(3.f + GetRandom()*0.3f, GetRandom() * 0.3f, .60f);
localEntities.emplace_back(ent);
}
// fragments
img = renderer->RegisterImage("Gfx/White.tga");
color = MakeVector4(1,1,1, 0.7f);
@ -664,13 +664,13 @@ namespace spades {
ent->SetBlockHitAction(ParticleSpriteEntity::Delete);
localEntities.emplace_back(ent);
}
// TODO: wave?
}
#pragma mark - Camera Control
enum { AutoFocusPoints = 4 };
void Client::UpdateAutoFocus(float dt) {
if (autoFocusEnabled && world && (int)cg_manualFocus) {
@ -681,7 +681,7 @@ namespace spades {
const Vector3 camDir = lastSceneDef.viewAxis[2].Normalize();
const Vector3 camX = lastSceneDef.viewAxis[0].Normalize() * measureRange;
const Vector3 camY = lastSceneDef.viewAxis[1].Normalize() * measureRange;
float distances[AutoFocusPoints * AutoFocusPoints];
std::size_t numValidDistances = 0;
Vector3 camDir1 = camDir - camX - camY;
@ -691,43 +691,43 @@ namespace spades {
Vector3 camDir2 = camDir1;
for (int y = 0; y < AutoFocusPoints; ++y) {
float dist = RayCastForAutoFocus(camOrigin, camDir2);
dist *= lenScale;
if (std::isfinite(dist) && dist > 0.8f) {
distances[numValidDistances++] = dist;
}
camDir2 += camDY;
}
camDir1 += camDX;
}
if (numValidDistances > 0) {
// Take median
std::sort(distances, distances + numValidDistances);
float dist = (numValidDistances & 1) ?
distances[numValidDistances >> 1] :
(distances[numValidDistances >> 1] + distances[(numValidDistances >> 1) - 1]) * 0.5f;
targetFocalLength = dist;
}
}
// Change the actual focal length slowly
{
float dist = 1.f / targetFocalLength;
float curDist = 1.f / focalLength;
const float maxSpeed = cg_autoFocusSpeed;
if (dist > curDist) {
curDist = std::min(dist, curDist + maxSpeed * dt);
} else {
curDist = std::max(dist, curDist - maxSpeed * dt);
}
focalLength = 1.f / curDist;
}
}
@ -735,7 +735,7 @@ namespace spades {
const Vector3 &direction)
{
SPAssert(world);
const auto &lastSceneDef = this->lastSceneDef;
World::WeaponRayCastResult result =
world->WeaponRayCast(origin,
@ -744,7 +744,7 @@ namespace spades {
if (result.hit) {
return Vector3::Dot(result.hitPos - origin, lastSceneDef.viewAxis[2]);
}
return std::nan(nullptr);
}

View File

@ -1,22 +1,22 @@
/*
Copyright (c) 2013 yvt
based on code of pysnip (c) Mathias Kaerlev 2011-2012.
This file is part of OpenSpades.
OpenSpades is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenSpades is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Client.h"
@ -53,9 +53,9 @@ static float nextRandom() {
namespace spades {
namespace client {
#pragma mark - Drawing
bool Client::ShouldRenderInThirdPersonView() {
if(world && world->GetLocalPlayer()){
if(!world->GetLocalPlayer()->IsAlive())
@ -66,7 +66,7 @@ namespace spades {
}
return false;
}
float Client::GetLocalFireVibration() {
float localFireVibration = 0.f;
localFireVibration = time - localFireVibrationTime;
@ -75,7 +75,7 @@ namespace spades {
localFireVibration = 0.f;
return localFireVibration;
}
float Client::GetAimDownZoomScale(){
if(world == nullptr ||
world->GetLocalPlayer() == nullptr ||
@ -97,27 +97,27 @@ namespace spades {
float aimDownState = GetAimDownState();
return 1.f + powf(aimDownState, 5.f) * delta;
}
SceneDefinition Client::CreateSceneDefinition() {
SPADES_MARK_FUNCTION();
int shakeLevel = cg_shake;
int shakeLevel = cg_shake;
SceneDefinition def;
def.time = (unsigned int)(time * 1000.f);
def.denyCameraBlur = true;
def.zFar = 200.f;
def.denyCameraBlur = true;
def.zFar = 200.f;
if(world){
IntVector3 fogColor = world->GetFogColor();
renderer->SetFogColor(MakeVector3(fogColor.x / 255.f,
fogColor.y / 255.f,
fogColor.z / 255.f));
Player *player = world->GetLocalPlayer();
def.blurVignette = .0f;
if(IsFollowing()){
int limit = 100;
// if current following player has left,
@ -133,7 +133,7 @@ namespace spades {
player = world->GetPlayer(followingPlayerId);
}
if(player){
float roll = 0.f;
float scale = 1.f;
float vibPitch = 0.f;
@ -143,7 +143,7 @@ namespace spades {
Vector3 center = player->GetEye();
Vector3 playerFront = player->GetFront2D();
Vector3 up = MakeVector3(0,0,-1);
if((!player->IsAlive()) && lastMyCorpse &&
player == world->GetLocalPlayer()){
center = lastMyCorpse->GetCenter();
@ -163,7 +163,7 @@ namespace spades {
}
}
}
float distance = 5.f;
if(player == world->GetLocalPlayer() &&
world->GetLocalPlayer()->GetTeamId() < 2 &&
@ -172,14 +172,14 @@ namespace spades {
float elapsedTime = time - lastAliveTime;
distance -= 3.f * expf(-elapsedTime * 1.f);
}
Vector3 eye = center;
//eye -= playerFront * 5.f;
//eye += up * 2.0f;
eye.x += cosf(followYaw) * cosf(followPitch) * distance;
eye.y += sinf(followYaw) * cosf(followPitch) * distance;
eye.z -= sinf(followPitch) * distance;
if(false){
// settings for making limbo stuff
eye = center;
@ -188,7 +188,7 @@ namespace spades {
eye += player->GetRight() *2.f;
scale *= .6f;
}
// try ray casting
GameMap::RayCastResult result;
result = map->CastRay2(center, (eye - center).Normalize(), 256);
@ -201,10 +201,10 @@ namespace spades {
eye += (center - eye).Normalize() * diff;
}
}
Vector3 front = center - eye;
front = front.Normalize();
if(FirstPersonSpectate == false){
def.viewOrigin = eye;
def.viewAxis[0] = -Vector3::Cross(up, front).Normalize();
@ -216,100 +216,100 @@ namespace spades {
def.viewAxis[1] = player->GetUp();
def.viewAxis[2] = player->GetFront();
}
def.fovY = (float)cg_fov * static_cast<float>(M_PI) /180.f;
def.fovX = atanf(tanf(def.fovY * .5f) *
renderer->ScreenWidth() /
renderer->ScreenHeight()) * 2.f;
// update initial spectate pos
// this is not used now, but if the local player is
// is spectating, this is used when he/she's no
// longer following
followPos = def.viewOrigin;
followVel = MakeVector3(0, 0, 0);
}else if(player->GetTeamId() >= 2){
// spectator view (noclip view)
Vector3 center = followPos;
Vector3 front;
Vector3 up = {0, 0, -1};
front.x = -cosf(followYaw) * cosf(followPitch);
front.y = -sinf(followYaw) * cosf(followPitch);
front.z = sinf(followPitch);
def.viewOrigin = center;
def.viewAxis[0] = -Vector3::Cross(up, front).Normalize();
def.viewAxis[1] = -Vector3::Cross(front, def.viewAxis[0]).Normalize();
def.viewAxis[2] = front;
def.fovY = (float)cg_fov * static_cast<float>(M_PI) /180.f;
def.fovX = atanf(tanf(def.fovY * .5f) *
renderer->ScreenWidth() /
renderer->ScreenHeight()) * 2.f;
// for 1st view, camera blur can be used
def.denyCameraBlur = false;
}else{
Vector3 front = player->GetFront();
Vector3 right = player->GetRight();
Vector3 up = player->GetUp();
if (shakeLevel >= 1) {
float localFireVibration = GetLocalFireVibration();
localFireVibration *= localFireVibration;
if(player->GetTool() == Player::ToolSpade) {
localFireVibration *= 0.4f;
}
roll += (nextRandom() - nextRandom()) * 0.03f * localFireVibration;
scale += nextRandom() * 0.04f * localFireVibration;
vibPitch += localFireVibration * (1.f - localFireVibration) * 0.01f;
vibYaw += sinf(localFireVibration * (float)M_PI * 2.f) * 0.001f;
def.radialBlur += localFireVibration * 0.2f;
// sprint bob
{
float sp = SmoothStep(GetSprintState());
vibYaw += sinf(player->GetWalkAnimationProgress() * static_cast<float>(M_PI) * 2.f) * 0.01f * sp;
roll -= sinf(player->GetWalkAnimationProgress() * static_cast<float>(M_PI) * 2.f) * 0.005f * (sp);
float p = cosf(player->GetWalkAnimationProgress() * static_cast<float>(M_PI) * 2.f);
p = p * p; p *= p; p *= p; p *= p;
vibPitch += p * 0.01f * sp;
}
}
if (shakeLevel >= 1) {
float localFireVibration = GetLocalFireVibration();
localFireVibration *= localFireVibration;
if(player->GetTool() == Player::ToolSpade) {
localFireVibration *= 0.4f;
}
roll += (nextRandom() - nextRandom()) * 0.03f * localFireVibration;
scale += nextRandom() * 0.04f * localFireVibration;
vibPitch += localFireVibration * (1.f - localFireVibration) * 0.01f;
vibYaw += sinf(localFireVibration * (float)M_PI * 2.f) * 0.001f;
def.radialBlur += localFireVibration * 0.2f;
// sprint bob
{
float sp = SmoothStep(GetSprintState());
vibYaw += sinf(player->GetWalkAnimationProgress() * static_cast<float>(M_PI) * 2.f) * 0.01f * sp;
roll -= sinf(player->GetWalkAnimationProgress() * static_cast<float>(M_PI) * 2.f) * 0.005f * (sp);
float p = cosf(player->GetWalkAnimationProgress() * static_cast<float>(M_PI) * 2.f);
p = p * p; p *= p; p *= p; p *= p;
vibPitch += p * 0.01f * sp;
}
}
scale /= GetAimDownZoomScale();
def.viewOrigin = player->GetEye();
def.viewAxis[0] = right;
def.viewAxis[1] = up;
def.viewAxis[2] = front;
def.fovY = (float)cg_fov * static_cast<float>(M_PI) /180.f;
def.fovX = atanf(tanf(def.fovY * .5f) *
renderer->ScreenWidth() /
renderer->ScreenHeight()) * 2.f;
// for 1st view, camera blur can be used
def.denyCameraBlur = false;
float aimDownState = GetAimDownState();
float per = aimDownState;
per *= per * per;
def.depthOfFieldFocalLength = per * 13.f + .054f;
def.blurVignette = .0f;
}
// add vibration for both 1st/3rd view
{
// add grenade vibration
@ -322,100 +322,100 @@ namespace spades {
vibPitch += (nextRandom() - nextRandom()) * 0.1f * grenVib;
vibYaw += (nextRandom() - nextRandom()) * 0.1f * grenVib;
scale -= (nextRandom()-nextRandom()) * 0.1f * grenVib;
def.radialBlur += grenVib * 0.8f;
}
}
// add roll / scale
{
Vector3 right = def.viewAxis[0];
Vector3 up = def.viewAxis[1];
def.viewAxis[0] = right * cosf(roll) - up * sinf(roll);
def.viewAxis[1] = up * cosf(roll) + right * sinf(roll);
def.fovX = atanf(tanf(def.fovX * .5f) * scale) * 2.f;
def.fovY = atanf(tanf(def.fovY * .5f) * scale) * 2.f;
def.fovX = atanf(tanf(def.fovX * .5f) * scale) * 2.f;
def.fovY = atanf(tanf(def.fovY * .5f) * scale) * 2.f;
}
{
Vector3 u = def.viewAxis[1];
Vector3 v = def.viewAxis[2];
def.viewAxis[1] = u * cosf(vibPitch) - v * sinf(vibPitch);
def.viewAxis[2] = v * cosf(vibPitch) + u * sinf(vibPitch);
}
{
Vector3 u = def.viewAxis[0];
Vector3 v = def.viewAxis[2];
def.viewAxis[0] = u * cosf(vibYaw) - v * sinf(vibYaw);
def.viewAxis[2] = v * cosf(vibYaw) + u * sinf(vibYaw);
}
{
float wTime = world->GetTime();
if(wTime < lastHurtTime + .15f &&
wTime >= lastHurtTime){
wTime >= lastHurtTime){
float per = 1.f - (wTime - lastHurtTime) / .15f;
per *= .5f - player->GetHealth() / 100.f * .3f;
def.blurVignette += per * 6.f;
}
if(wTime < lastHurtTime + .2f &&
wTime >= lastHurtTime){
wTime >= lastHurtTime){
float per = 1.f - (wTime - lastHurtTime) / .2f;
per *= .5f - player->GetHealth() / 100.f * .3f;
def.saturation *= std::max(0.f, 1.f - per * 4.f);
}
}
def.zNear = 0.05f;
def.skipWorld = false;
}else{
def.viewOrigin = MakeVector3(256, 256, 4);
def.viewAxis[0] = MakeVector3(-1, 0, 0);
def.viewAxis[1] = MakeVector3(0, 1, 0);
def.viewAxis[2] = MakeVector3(0, 0, 1);
def.fovY = (float)cg_fov * static_cast<float>(M_PI) /180.f;
def.fovX = atanf(tanf(def.fovY * .5f) *
renderer->ScreenWidth() /
renderer->ScreenHeight()) * 2.f;
def.zNear = 0.05f;
def.skipWorld = false;
}
}else{
def.viewOrigin = MakeVector3(0, 0, 0);
def.viewAxis[0] = MakeVector3(1, 0, 0);
def.viewAxis[1] = MakeVector3(0, 0, -1);
def.viewAxis[2] = MakeVector3(0, 0, 1);
def.fovY = (float)cg_fov * static_cast<float>(M_PI) /180.f;
def.fovX = atanf(tanf(def.fovY * .5f) *
renderer->ScreenWidth() /
renderer->ScreenHeight()) * 2.f;
def.zNear = 0.05f;
def.skipWorld = true;
renderer->SetFogColor(MakeVector3(0,0,0));
}
if (def.viewOrigin.z < 0.f) {
// Need to move the far plane because there's no vertical fog
def.zFar -= def.viewOrigin.z;
}
if (def.viewOrigin.z < 0.f) {
// Need to move the far plane because there's no vertical fog
def.zFar -= def.viewOrigin.z;
}
SPAssert(!isnan(def.viewOrigin.x));
SPAssert(!isnan(def.viewOrigin.y));
SPAssert(!isnan(def.viewOrigin.z));
def.radialBlur = std::min(def.radialBlur, 1.f);
if ((int)cg_manualFocus) {
// Depth of field is manually controlled
def.depthOfFieldNearBlurStrength = def.depthOfFieldFarBlurStrength =
@ -425,29 +425,29 @@ namespace spades {
def.depthOfFieldNearBlurStrength = cg_depthOfFieldAmount;
def.depthOfFieldFarBlurStrength = 0.f;
}
return def;
}
void Client::AddGrenadeToScene(spades::client::Grenade *g) {
SPADES_MARK_FUNCTION();
IModel *model;
model = renderer->RegisterModel("Models/Weapons/Grenade/Grenade.kv6");
if(g->GetPosition().z > 63.f) {
// work-around for water refraction problem
return;
}
ModelRenderParam param;
Matrix4 mat = Matrix4::Scale(0.03f);
mat = Matrix4::Translate(g->GetPosition()) * mat;
param.matrix = mat;
renderer->RenderModel(model, param);
}
void Client::AddDebugObjectToScene(const spades::OBB3 &obb, const Vector4& color) {
const Matrix4& mat = obb.m;
Vector3 v[2][2][2];
@ -459,23 +459,23 @@ namespace spades {
v[1][0][1] = (mat * MakeVector3(1,0,1)).GetXYZ();
v[1][1][0] = (mat * MakeVector3(1,1,0)).GetXYZ();
v[1][1][1] = (mat * MakeVector3(1,1,1)).GetXYZ();
renderer->AddDebugLine(v[0][0][0], v[1][0][0], color);
renderer->AddDebugLine(v[0][0][1], v[1][0][1], color);
renderer->AddDebugLine(v[0][1][0], v[1][1][0], color);
renderer->AddDebugLine(v[0][1][1], v[1][1][1], color);
renderer->AddDebugLine(v[0][0][0], v[0][1][0], color);
renderer->AddDebugLine(v[0][0][1], v[0][1][1], color);
renderer->AddDebugLine(v[1][0][0], v[1][1][0], color);
renderer->AddDebugLine(v[1][0][1], v[1][1][1], color);
renderer->AddDebugLine(v[0][0][0], v[0][0][1], color);
renderer->AddDebugLine(v[0][1][0], v[0][1][1], color);
renderer->AddDebugLine(v[1][0][0], v[1][0][1], color);
renderer->AddDebugLine(v[1][1][0], v[1][1][1], color);
}
void Client::DrawCTFObjects() {
SPADES_MARK_FUNCTION();
CTFGameMode *mode = static_cast<CTFGameMode *>(world->GetMode());
@ -488,15 +488,15 @@ namespace spades {
Vector3 color = {
col.x / 255.f, col.y / 255.f, col.z / 255.f
};
ModelRenderParam param;
param.customColor = color;
// draw base
param.matrix = Matrix4::Translate(team.basePos);
param.matrix = param.matrix * Matrix4::Scale(.3f);
renderer->RenderModel(base, param);
// draw flag
if(!mode->GetTeam(1-tId).hasIntel){
param.matrix = Matrix4::Translate(team.flagPos);
@ -505,7 +505,7 @@ namespace spades {
}
}
}
void Client::DrawTCObjects() {
SPADES_MARK_FUNCTION();
TCGameMode *mode = static_cast<TCGameMode *>(world->GetMode());
@ -523,26 +523,26 @@ namespace spades {
Vector3 color = {
col.x / 255.f, col.y / 255.f, col.z / 255.f
};
ModelRenderParam param;
param.customColor = color;
// draw base
param.matrix = Matrix4::Translate(t->pos);
param.matrix = param.matrix * Matrix4::Scale(.3f);
renderer->RenderModel(base, param);
}
}
void Client::DrawScene(){
SPADES_MARK_FUNCTION();
renderer->StartScene(lastSceneDef);
if(world){
Player *p = world->GetLocalPlayer();
for(size_t i = 0; i < world->GetNumPlayerSlots(); i++)
if(world->GetPlayer(static_cast<unsigned int>(i))){
SPAssert(clientPlayers[i]);
@ -552,7 +552,7 @@ namespace spades {
for(size_t i = 0; i < nades.size(); i++){
AddGrenadeToScene(nades[i]);
}
{
for(auto& c: corpses){
Vector3 center = c->GetCenter();
@ -561,19 +561,19 @@ namespace spades {
c->AddToScene();
}
}
if( IGameMode::m_CTF == world->GetMode()->ModeType() ){
DrawCTFObjects();
} else if( IGameMode::m_TC == world->GetMode()->ModeType() ){
DrawTCObjects();
}
{
for(auto& ent: localEntities){
ent->Render3D();
}
}
// draw block cursor
// FIXME: don't use debug line
if(p){
@ -589,9 +589,9 @@ namespace spades {
}else{
blocks.push_back(p->GetBlockCursorPos());
}
bool active = p->IsBlockCursorActive();
Vector4 color = {1,1,1,1};
if(!active)
color = Vector4(1,1,0,1);
@ -599,12 +599,12 @@ namespace spades {
color = MakeVector4(1,0,0,1);
if(!active)
color.w *= 0.5f;
for(size_t i = 0; i < blocks.size(); i++){
IntVector3& v = blocks[i];
if(active) {
renderer->AddDebugLine(MakeVector3(v.x, v.y, v.z),
MakeVector3(v.x+1, v.y, v.z),
color);
@ -620,7 +620,7 @@ namespace spades {
renderer->AddDebugLine(MakeVector3(v.x, v.y, v.z),
MakeVector3(v.x+1, v.y, v.z),
color);
renderer->AddDebugLine(MakeVector3(v.x, v.y, v.z),
MakeVector3(v.x, v.y+1, v.z),
color);
@ -633,7 +633,7 @@ namespace spades {
renderer->AddDebugLine(MakeVector3(v.x+1, v.y, v.z+1),
MakeVector3(v.x+1, v.y+1, v.z+1),
color);
renderer->AddDebugLine(MakeVector3(v.x, v.y, v.z),
MakeVector3(v.x, v.y, v.z+1),
color);
@ -648,7 +648,7 @@ namespace spades {
color);
}else{
// not active
const float ln = 0.1f;
{
float xx = v.x, yy = v.y, zz = v.z;
@ -698,20 +698,20 @@ namespace spades {
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx, yy-ln, zz), color);
renderer->AddDebugLine(Vector3(xx, yy, zz), Vector3(xx, yy, zz-ln), color);
}
}
// --- one block drawn
} // end for
} // p->IsReadyToUseTool
}
}
for(size_t i = 0; i < flashDlights.size(); i++)
renderer->AddLight(flashDlights[i]);
flashDlightsOld.clear();
flashDlightsOld.swap(flashDlights);
// draw player hottrack
// FIXME: don't use debug line
{
@ -721,7 +721,7 @@ namespace spades {
IntVector3 col = world->GetTeam(hottracked->GetTeamId()).color;
Vector4 color = Vector4::Make( col.x / 255.f, col.y / 255.f, col.z / 255.f, 1.f );
Vector4 color2 = Vector4::Make( 1, 1, 1, 1);
Player::HitBoxes hb = hottracked->GetHitBoxes();
AddDebugObjectToScene(hb.head, (tag & hit_Head) ? color2 : color );
AddDebugObjectToScene(hb.torso, (tag & hit_Torso) ? color2 : color );
@ -730,29 +730,29 @@ namespace spades {
AddDebugObjectToScene(hb.limbs[2], (tag & hit_Arms) ? color2 : color );
}
}
renderer->EndScene();
}
Vector3 Client::Project(spades::Vector3 v){
v -= lastSceneDef.viewOrigin;
// transform to NDC
Vector3 v2;
v2.x = Vector3::Dot(v, lastSceneDef.viewAxis[0]);
v2.y = Vector3::Dot(v, lastSceneDef.viewAxis[1]);
v2.z = Vector3::Dot(v, lastSceneDef.viewAxis[2]);
float tanX = tanf(lastSceneDef.fovX * .5f);
float tanY = tanf(lastSceneDef.fovY * .5f);
v2.x /= tanX * v2.z;
v2.y /= tanY * v2.z;
// transform to IRenderer 2D coord
v2.x = (v2.x + 1.f) / 2.f * renderer->ScreenWidth();
v2.y = (-v2.y + 1.f) / 2.f * renderer->ScreenHeight();
return v2;
}

View File

@ -1,21 +1,21 @@
/*
Copyright (c) 2013 yvt
This file is part of OpenSpades.
OpenSpades is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenSpades is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Corpse.h"
@ -38,29 +38,29 @@ namespace spades {
Player *p):
renderer(renderer), map(map) {
SPADES_MARK_FUNCTION();
IntVector3 col = p->GetWorld()->GetTeam(p->GetTeamId()).color;
color = MakeVector3(col.x / 255.f,
col.y / 255.f,
col.z / 255.f);
bool crouch = p->GetInput().crouch;
Vector3 front = p->GetFront();
float yaw = atan2(front.y, front.x) + static_cast<float>(M_PI) * .5f;
//float pitch = -atan2(front.z, sqrt(front.x * front.x + front.y * front.y));
// lower axis
Matrix4 lower = Matrix4::Translate(p->GetOrigin());
lower = lower * Matrix4::Rotate(MakeVector3(0,0,1),
yaw);
Matrix4 torso;
if(crouch){
lower = lower * Matrix4::Translate(0, 0, -0.4f);
torso = lower * Matrix4::Translate(0, 0, -0.3f);
SetNode(Torso1,
torso*MakeVector3(0.4f, -.15f, 0.1f));
SetNode(Torso2,
@ -69,20 +69,20 @@ namespace spades {
torso*MakeVector3(-0.4f, .8f, 0.7f));
SetNode(Torso4,
torso*MakeVector3(0.4f, .8f, 0.7f));
SetNode(Leg1,
lower*MakeVector3(-0.4f, .1f, 1.f));
SetNode(Leg2,
lower*MakeVector3(0.4f, .1f, 1.f));
SetNode(Arm1,
torso*MakeVector3(0.2f, -.4f, .2f));
SetNode(Arm2,
torso*MakeVector3(-0.2f, -.4f, .2f));
}else{
torso = lower * Matrix4::Translate(0, 0, -1.1f);
SetNode(Torso1,
torso*MakeVector3(0.4f, 0.f, 0.1f));
SetNode(Torso2,
@ -91,29 +91,29 @@ namespace spades {
torso*MakeVector3(-0.4f, .0f, 1.f));
SetNode(Torso4,
torso*MakeVector3(0.4f, .0f, 1.f));
SetNode(Leg1,
lower*MakeVector3(-0.4f, .0f, 1.f));
SetNode(Leg2,
lower*MakeVector3(0.4f, .0f, 1.f));
SetNode(Arm1,
torso*MakeVector3(0.2f, -.4f, .2f));
SetNode(Arm2,
torso*MakeVector3(-0.2f, -.4f, .2f));
}
SetNode(Head, (nodes[Torso1].pos + nodes[Torso2].pos)
* .5f + MakeVector3(0,0,-0.6f));
}
static float VelNoise() {
return (GetRandom() - GetRandom()) * 2.f;
}
void Corpse::SetNode(NodeType n, spades::Vector3 v){
SPAssert(n >= 0); SPAssert(n < NodeCount);
nodes[n].pos = v;
@ -122,16 +122,16 @@ namespace spades {
0.f);
nodes[n].lastPos = v;
nodes[n].lastForce = MakeVector3(0, 0,0);
}
void Corpse::SetNode(NodeType n, spades::Vector4 v){
SetNode(n, v.GetXYZ());
}
Corpse::~Corpse(){
}
void Corpse::Spring(NodeType n1,
NodeType n2,
float distance,
@ -145,18 +145,18 @@ namespace spades {
float dist = diff.GetLength();
Vector3 force = diff.Normalize() * (distance - dist);
force *= dt * 50.f;
b.vel += force;
a.vel -= force;
b.pos += force / (dt * 50.f) * 0.5f;
a.pos -= force / (dt * 50.f) * 0.5f;
Vector3 velMid = (a.vel + b.vel) * .5f;
float dump = 1.f - powf(.1f, dt);
a.vel += (velMid - a.vel) * dump;
b.vel += (velMid - b.vel) * dump;
}
void Corpse::Spring(NodeType n1a,
NodeType n1b,
@ -174,20 +174,20 @@ namespace spades {
float dist = diff.GetLength();
Vector3 force = diff.Normalize() * (distance - dist);
force *= dt * 50.f;
b.vel += force;
force *= .5f;
x.vel -= force;
y.vel -= force;
Vector3 velMid = (x.vel + y.vel) * .25f + b.vel * .5f;
float dump = 1.f - powf(.05f, dt);
x.vel += (velMid - x.vel) * dump;
y.vel += (velMid - y.vel) * dump;
b.vel += (velMid - b.vel) * dump;
}
static float MyACos(float v){
SPAssert(!isnan(v));
if(v >= 1.f) return 0.f;
@ -214,48 +214,48 @@ namespace spades {
float ln1 = d1.GetLength();
float ln2 = d2.GetLength();
float dot = Vector3::Dot(d1, d2) / (ln1 * ln2 + 0.0000001f);
if(dot >= minDot && dot <= maxDot)
return;
Vector3 diff = n2.pos - n1.pos;
float strength = 0.f;
Vector3 a1 = Vector3::Cross(d1, diff);
a1 = Vector3::Cross(d1, a1).Normalize();
Vector3 a2 = Vector3::Cross(d2, diff);
a2 = Vector3::Cross(d2, a2).Normalize();
//a1=-a1; a2=-a2;
//a1 = -a1;
a2 = -a2;
if(dot > maxDot){
strength = MyACos(dot) - MyACos(maxDot);
}else if(dot < minDot){
strength = MyACos(dot) - MyACos(minDot);
}
SPAssert(!isnan(strength));
strength *= 20.f;
strength *= dt;
a1 *= strength;
a2 *= strength;
a2 *= 0.f;
n2.vel += a1;
n1.vel += a2;
nBase.vel -= a1 + a2;
/*
d1 += a1 * 0.01;
d2 += a2 * 0.01;
float nd = Vector3::Dot(d1, d2) / (d1.GetLength() * d2.GetLength());
if(dot > maxDot){
if(nd < dot)
printf("GOOD %f -> %f\n", dot, nd);
@ -279,42 +279,42 @@ namespace spades {
Vector3 diff = n2.pos - n1.pos;
float ln1 = diff.GetLength();
float dot = Vector3::Dot(diff, dir) / (ln1 + 0.000000001f);
if(dot >= minDot && dot <= maxDot)
return;
float strength = 0.f;
Vector3 a1 = Vector3::Cross(dir, diff);
a1 = Vector3::Cross(diff, a1).Normalize();
Vector3 a2 = -a1;
//a1=-a1; a2=-a2;
//a1 = -a1;
if(dot > maxDot){
strength = MyACos(dot) - MyACos(maxDot);
}else if(dot < minDot){
strength = MyACos(dot) - MyACos(minDot);
}
SPAssert(!isnan(strength));
strength *= 100.f;
strength *= dt;
a1 *= strength;
a2 *= strength;
n2.vel += a1;
n1.vel += a2;
//nBase.vel -= a1 + a2;
/*
d1 += a1 * 0.01;
d2 += a2 * 0.01;
float nd = Vector3::Dot(d1, d2) / (d1.GetLength() * d2.GetLength());
if(dot > maxDot){
if(nd < dot)
printf("GOOD %f -> %f\n", dot, nd);
@ -327,11 +327,11 @@ namespace spades {
printf("BAD %f -> %f\n", dot, nd);
}*/
}
static float fractf(float v){
return v - floorf(v);
}
static void CheckEscape(GameMap *map,
IntVector3 hitBlock,
IntVector3 a, IntVector3 b,
@ -370,31 +370,31 @@ namespace spades {
SPAssert(false);
return;
}
if(dist < bestDist){
bestDist = dist;
bestDir = dir;
}
}
void Corpse::LineCollision(NodeType a, NodeType b, float dt){
if(!r_corpseLineCollision)
return;
Node& n1 = nodes[a];
Node& n2 = nodes[b];
IntVector3 hitBlock;
if(map->CastRay(n1.lastPos, n2.lastPos, 16.f, hitBlock)) {
GameMap::RayCastResult res1 = map->CastRay2(n1.lastPos, n2.lastPos - n1.lastPos, 8);
GameMap::RayCastResult res2 = map->CastRay2(n2.lastPos, n1.lastPos - n2.lastPos, 8);
if(!res1.hit) return;
if(!res2.hit) return;
if(res1.startSolid || res2.startSolid){
return;
}
// really hit?
if(Vector3::Dot(res1.hitPos - n1.lastPos, n2.lastPos - n1.lastPos)
> (n2.pos-n1.pos).GetPoweredLength()){
@ -412,23 +412,23 @@ namespace spades {
< 0.f){
return;
}
Vector3 blockPos;
blockPos.x = hitBlock.x + .5f;
blockPos.y = hitBlock.y + .5f;
blockPos.z = hitBlock.z + .5f;
float inlen = (res1.hitPos - res2.hitPos).GetLength();
IntVector3 ivec = {0, 0, 0};
ivec.x += res1.normal.x;
ivec.y += res1.normal.y;
ivec.z += res1.normal.z;
ivec.x += res2.normal.x;
ivec.y += res2.normal.y;
ivec.z += res2.normal.z;
Vector3 dir = {0.f, 0.f, 0.f};
if(ivec.x == 0 && ivec.y == 0 && ivec.z == 0) {
// hanging. which direction to escape?
@ -474,25 +474,25 @@ namespace spades {
dir.x = ivec.x;
dir.y = ivec.y;
dir.z = ivec.z;
Vector3 normDir = dir; // |D|
n1.vel -= normDir * std::min(Vector3::Dot(normDir, n1.vel), 0.f);
n2.vel -= normDir * std::min(Vector3::Dot(normDir, n2.vel), 0.f);
dir *= dt * inlen * 5.f;
n1.vel += dir;
n2.vel += dir;
// friction
n1.vel -= (n1.vel - normDir * Vector3::Dot(normDir, n1.vel)) * .2f;
n2.vel -= (n2.vel - normDir * Vector3::Dot(normDir, n2.vel)) * .2f;
}
}
void Corpse::AngularMomentum(int eId,
NodeType a,
NodeType b){
@ -503,19 +503,19 @@ namespace spades {
e.node1 = a; e.node2 = b;
return;
}
Vector3 force = e.lastVelDiff - e.velDiff;
force *= .5f;
nodes[b].vel += force;
nodes[a].vel -= force;
e.lastVelDiff = e.velDiff;
}
void Corpse::ApplyConstraint(float dt) {
SPADES_MARK_FUNCTION();
AngularMomentum(0,
Torso1, Torso2);
AngularMomentum(1,
@ -532,23 +532,23 @@ namespace spades {
Torso3, Leg1);
AngularMomentum(7,
Torso4, Leg2);
Spring(Torso1, Torso2,
0.8f, dt);
Spring(Torso3, Torso4,
0.8f, dt);
Spring(Torso1, Torso4,
0.9f, dt);
Spring(Torso2, Torso3,
0.9f, dt);
Spring(Torso1, Torso3,
1.204f, dt);
Spring(Torso2, Torso4,
1.204f, dt);
Spring(Arm1, Torso1,
1.f, dt);
Spring(Arm2, Torso2,
@ -557,33 +557,33 @@ namespace spades {
1.f, dt);
Spring(Leg2, Torso4,
1.f, dt);
AngleSpring(Torso1,
Arm1, Torso3,
-1.f, 0.6f, dt);
AngleSpring(Torso2,
Arm2, Torso4,
-1.f, 0.6f, dt);
AngleSpring(Torso3,
Leg1, Torso2,
-1.f, -0.2f, dt);
AngleSpring(Torso4,
Leg2, Torso1,
-1.f, -0.2f, dt);
Spring(Torso1, Torso2, Head,
.6f, dt);
/*
AngleSpring(Torso1,
Torso2, Head,
0.5f, 1.f, dt);
AngleSpring(Torso2,
Torso1, Head,
0.5f, 1.f, dt);
*/
LineCollision(Torso1, Torso2, dt);
LineCollision(Torso2, Torso3, dt);
LineCollision(Torso3, Torso4, dt);
@ -594,57 +594,57 @@ namespace spades {
LineCollision(Torso2, Arm2, dt);
LineCollision(Torso3, Leg1, dt);
LineCollision(Torso4, Leg2, dt);
return;
AngleSpring(Torso4,
Torso1, Head,
0.5f, 1.f, dt);
AngleSpring(Torso3,
Torso2, Head,
0.5f, 1.f, dt);
AngleSpring(Torso4,
Torso2, Head,
0.5f, 1.f, dt);
AngleSpring(Torso3,
Torso1, Head,
0.5f, 1.f, dt);
}
void Corpse::Update(float dt) {
SPADES_MARK_FUNCTION();
float damp = 1.f;
float damp2 = 1.f;
float damp2 = 1.f;
if(dt > 0.f){
damp = powf(.9f, dt);
damp2 = powf(.371f, dt);
}
}
//dt *= 0.1f;
for(int i = 0; i <NodeCount; i++){
Node& node = nodes[i];
Vector3 oldPos = node.lastPos;
node.pos += node.vel * dt;
SPAssert(!isnan(node.pos.x));
SPAssert(!isnan(node.pos.y));
SPAssert(!isnan(node.pos.z));
if(node.pos.z > 63.f){
node.vel.z -= dt * 6.f; // buoyancy
node.vel *= damp;
}else{
node.vel.z += dt * 32.f; // gravity
node.vel.z *= damp2;
}
node.vel.z += dt * 32.f; // gravity
node.vel.z *= damp2;
}
//node.vel *= damp;
if(!map->ClipBox(oldPos.x, oldPos.y, oldPos.z)){
if(map->ClipBox(node.pos.x,
oldPos.y,
oldPos.z)){
@ -652,11 +652,11 @@ namespace spades {
if(fabsf(node.vel.x) < .3f)
node.vel.x = 0.f;
node.pos.x = oldPos.x;
node.vel.y *= .5f;
node.vel.z *= .5f;
}
if(map->ClipBox(node.pos.x,
node.pos.y,
oldPos.z)){
@ -664,11 +664,11 @@ namespace spades {
if(fabsf(node.vel.y) < .3f)
node.vel.y = 0.f;
node.pos.y = oldPos.y;
node.vel.x *= .5f;
node.vel.z *= .5f;
}
if(map->ClipBox(node.pos.x,
node.pos.y,
node.pos.z)){
@ -676,18 +676,18 @@ namespace spades {
if(fabsf(node.vel.z) < .3f)
node.vel.z = 0.f;
node.pos.z = oldPos.z;
node.vel.x *= .5f;
node.vel.y *= .5f;
}
if(map->ClipBox(node.pos.x, node.pos.y, node.pos.z)){
// TODO: getting out block
//node.pos = oldPos;
//node.vel *= .5f;
}
}
/*
if(map->ClipBox(node.pos.x,
node.pos.y,
@ -718,23 +718,23 @@ namespace spades {
}
node.vel *= .8f;
//node.pos = oldPos;
if(node.vel.GetLength() < .02f){
node.vel *= 0.f;
}
}*/
node.lastPos = node.pos;
node.lastForce = node.vel;
}
ApplyConstraint(dt);
for(int i = 0; i <NodeCount; i++){
nodes[i].lastForce = nodes[i].vel - nodes[i].lastForce;
}
}
void Corpse::AddToScene() {
if(false){
// debug line only
@ -751,42 +751,42 @@ namespace spades {
renderer->AddDebugLine(nodes[Torso4].pos,
nodes[Torso1].pos,
col);
renderer->AddDebugLine(nodes[Torso2].pos,
nodes[Torso4].pos,
col);
renderer->AddDebugLine(nodes[Torso1].pos,
nodes[Torso3].pos,
col);
renderer->AddDebugLine(nodes[Torso1].pos,
nodes[Arm1].pos,
col);
renderer->AddDebugLine(nodes[Torso2].pos,
nodes[Arm2].pos,
col);
renderer->AddDebugLine(nodes[Torso3].pos,
nodes[Leg1].pos,
col);
renderer->AddDebugLine(nodes[Torso4].pos,
nodes[Leg2].pos,
col);
renderer->AddDebugLine((nodes[Torso1].pos+nodes[Torso2].pos)*.5f,
nodes[Head].pos,
col);
return;
}
ModelRenderParam param;
param.customColor = color;
IModel *model;
Matrix4 scaler = Matrix4::Scale(.1f);
// draw torso
Matrix4 torso;
Vector3 tX, tY;
@ -801,9 +801,9 @@ namespace spades {
tY = Vector3::Cross(tX, tZ).Normalize();
Vector3 tOrigin = tY1 * .5f;
torso = Matrix4::FromAxis(tX, -tZ, -tY, tOrigin);
param.matrix = torso * scaler;
model = renderer->RegisterModel
("Models/Player/Torso.kv6");
renderer->RenderModel(model, param);
@ -812,13 +812,13 @@ namespace spades {
{
Vector3 headBase =
(torso * MakeVector3(0.0f, 0.f, 0.f)).GetXYZ();
model = renderer->RegisterModel
("Models/Player/Head.kv6");
Vector3 aX, aY, aZ;
Vector3 center = (nodes[Torso1].pos + nodes[Torso2].pos) * .5f;
aZ = nodes[Head].pos - center;
aZ = -torso.GetAxis(2);
aZ = aZ.Normalize();
@ -826,73 +826,73 @@ namespace spades {
aY = Vector3::Cross(aY, aZ).Normalize();
aX = Vector3::Cross(aY, aZ).Normalize();
param.matrix = Matrix4::FromAxis(-aX, aY, -aZ, headBase) * scaler;
renderer->RenderModel(model, param);
}
// draw Arms
{
Vector3 arm1Base =
(torso * MakeVector3(0.4f, 0.f, 0.2f)).GetXYZ();
Vector3 arm2Base =
(torso * MakeVector3(-0.4f, 0.f, 0.2f)).GetXYZ();
model = renderer->RegisterModel
("Models/Player/Arm.kv6");
Vector3 aX, aY, aZ;
aZ = nodes[Arm1].pos - nodes[Torso1].pos;
aZ = aZ.Normalize();
aY = nodes[Torso2].pos - nodes[Torso1].pos;
aY = Vector3::Cross(aY, aZ).Normalize();
aX = Vector3::Cross(aY, aZ).Normalize();
param.matrix = Matrix4::FromAxis(aX, aY, aZ, arm1Base) * scaler;
renderer->RenderModel(model, param);
aZ = nodes[Arm2].pos - nodes[Torso2].pos;
aZ = aZ.Normalize();
aY = nodes[Torso1].pos - nodes[Torso2].pos;
aY = Vector3::Cross(aY, aZ).Normalize();
aX = Vector3::Cross(aY, aZ).Normalize();
param.matrix = Matrix4::FromAxis(aX, aY, aZ, arm2Base) * scaler;
renderer->RenderModel(model, param);
}
// draw Leg
{
Vector3 leg1Base =
(torso * MakeVector3(0.25f, 0.f, 0.9f)).GetXYZ();
Vector3 leg2Base =
(torso * MakeVector3(-0.25f, 0.f, 0.9f)).GetXYZ();
model = renderer->RegisterModel
("Models/Player/Leg.kv6");
Vector3 aX, aY, aZ;
aZ = nodes[Leg1].pos - nodes[Torso3].pos;
aZ = aZ.Normalize();
aY = nodes[Torso1].pos - nodes[Torso2].pos;
aY = Vector3::Cross(aY, aZ).Normalize();
aX = Vector3::Cross(aY, aZ).Normalize();
param.matrix = Matrix4::FromAxis(aX, aY, aZ, leg1Base) * scaler;
renderer->RenderModel(model, param);
aZ = nodes[Leg2].pos - nodes[Torso4].pos;
aZ = aZ.Normalize();
aY = nodes[Torso1].pos - nodes[Torso2].pos;
aY = Vector3::Cross(aY, aZ).Normalize();
aX = Vector3::Cross(aY, aZ).Normalize();
param.matrix = Matrix4::FromAxis(aX, aY, aZ, leg2Base) * scaler;
renderer->RenderModel(model, param);
}
}
Vector3 Corpse::GetCenter() {
Vector3 v = {0,0,0};
for(int i = 0; i < NodeCount; i++)
@ -900,12 +900,12 @@ namespace spades {
v *= 1.f / (float)NodeCount;
return v;
}
bool Corpse::IsVisibleFrom(spades::Vector3 eye){
// distance culled?
if((eye - GetCenter()).GetLength() > 150.f)
return false;
for(int i = 0; i < NodeCount; i++){
IntVector3 outBlk;
if(map->CastRay(eye, nodes[i].pos,
@ -914,7 +914,7 @@ namespace spades {
}
return false;
}
void Corpse::AddImpulse(spades::Vector3 v){
for(int i = 0; i < NodeCount; i++)
nodes[i].vel += v;

View File

@ -1,21 +1,21 @@
/*
Copyright (c) 2013 yvt
This file is part of OpenSpades.
OpenSpades is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenSpades is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
*/
#include "GameMapWrapper.h"
@ -31,51 +31,51 @@
namespace spades {
namespace client {
GameMapWrapper::GameMapWrapper(GameMap *mp):
map(mp) {
SPADES_MARK_FUNCTION();
width = mp->Width();
height = mp->Height();
depth = mp->Depth();
linkMap = new uint8_t[width*height*depth];
memset(linkMap, 0, width * height * depth);
}
GameMapWrapper::~GameMapWrapper() {
SPADES_MARK_FUNCTION();
delete[] linkMap;
}
void GameMapWrapper::Rebuild() {
SPADES_MARK_FUNCTION();
Stopwatch stopwatch;
GameMap *m = map;
memset(linkMap, 0, width * height * depth);
for(int x = 0; x < width; x++)
for(int y = 0; y < height; y++)
SetLink(x, y, depth - 1, Root);
Deque<CellPos> queue(width * height * 2);
for(int x = 0; x < width; x++)
for(int y = 0; y < height; y++)
if(m->IsSolid(x, y, depth - 2)){
SetLink(x, y, depth-2, PositiveZ);
queue.Push(CellPos(x, y, depth - 2));
}
while(!queue.IsEmpty()){
CellPos p = queue.Front();
queue.Shift();
int x = p.x, y = p.y, z = p.z;
if(p.x > 0 && m->IsSolid(x-1,y,z) && GetLink(x-1,y,z) == Invalid){
SetLink(x-1, y, z, PositiveX);
queue.Push(CellPos(x-1, y, z));
@ -101,28 +101,28 @@ namespace spades {
queue.Push(CellPos(x, y, z+1));
}
}
SPLog("%.3f msecs to rebuild",
stopwatch.GetTime() * 1000.);
}
void GameMapWrapper::AddBlock(int x, int y, int z, uint32_t color){
SPADES_MARK_FUNCTION();
GameMap *m = map;
if(GetLink(x, y, z) != Invalid) {
SPAssert(m->IsSolid(x, y, z));
return;
}
m->Set(x, y, z, true, color);
if(GetLink(x, y, z) != Invalid) {
return;
}
LinkType l = Invalid;
if(x > 0 && m->IsSolid(x - 1, y, z) &&
GetLink(x-1, y, z) != Invalid){
@ -155,7 +155,7 @@ namespace spades {
SPAssert(GetLink(x, y, z+1) != NegativeZ);
}
SetLink(x, y, z, l);
if(l == Invalid)
return;
// if there's invalid block around this block,
@ -165,12 +165,12 @@ namespace spades {
while(!queue.IsEmpty()){
CellPos p = queue.Front();
queue.Shift();
int x = p.x, y = p.y, z = p.z;
SPAssert(m->IsSolid(x,y,z));
LinkType thisLink = GetLink(x, y, z);
if(p.x > 0 && m->IsSolid(x-1,y,z) && GetLink(x-1,y,z) == Invalid &&
thisLink != NegativeX){
SetLink(x-1, y, z, PositiveX);
@ -202,50 +202,50 @@ namespace spades {
queue.Push(CellPos(x, y, z+1));
}
}
}
template<typename T>
static inline bool EqualTwoCond(T a, T b, T c, bool cond) {
return a == b || (cond && a == c);
}
template<typename T>
static inline bool EqualTwoCond(T a, T b, T c, bool cond) {
return a == b || (cond && a == c);
}
std::vector<CellPos> GameMapWrapper::RemoveBlocks(const std::vector<CellPos>& cells) {
SPADES_MARK_FUNCTION();
if(cells.empty())
return std::vector<CellPos>();
GameMap *m = map;
// solid, but unlinked cells
std::vector<CellPos> unlinkedCells;
Deque<CellPos> queue(1024);
// unlink children
for(size_t i = 0; i < cells.size(); i++){
CellPos pos = cells[i];
m->Set(pos.x, pos.y, pos.z, false, 0);
// if(GetLink(pos.x, pos.y, pos.z) == Invalid){
// this block is already disconnected.
// }
if(GetLink(pos.x, pos.y, pos.z) == Marked){
continue;
}
// this block is already disconnected.
// }
if(GetLink(pos.x, pos.y, pos.z) == Marked){
continue;
}
SPAssert(GetLink(pos.x, pos.y, pos.z) != Root);
SetLink(pos.x, pos.y, pos.z, Invalid);
queue.Push(pos);
while(!queue.IsEmpty()){
pos = queue.Front();
queue.Shift();
if(m->IsSolid(pos.x, pos.y, pos.z))
unlinkedCells.push_back(pos);
// don't "continue;" when non-solid
int x = pos.x, y = pos.y, z = pos.z;
if(x > 0 && EqualTwoCond(GetLink(x-1,y,z), PositiveX, Invalid, m->IsSolid(x-1, y, z))){
SetLink(x-1, y, z, Marked);
@ -272,18 +272,18 @@ namespace spades {
queue.Push(CellPos(x, y, z+1));
}
}
}
// remove "visited" mark
// remove "visited" mark
for(size_t i = 0; i < unlinkedCells.size(); i++){
const CellPos& pos = unlinkedCells[i];
if(GetLink(pos.x, pos.y, pos.z) == Marked)
SetLink(pos.x, pos.y, pos.z, Invalid);
}
const CellPos& pos = unlinkedCells[i];
if(GetLink(pos.x, pos.y, pos.z) == Marked)
SetLink(pos.x, pos.y, pos.z, Invalid);
}
SPAssert(queue.IsEmpty());
// start relinking
for(size_t i = 0; i < unlinkedCells.size(); i++){
const CellPos& pos = unlinkedCells[i];
@ -293,7 +293,7 @@ namespace spades {
// don't use SPAssert()
continue;
}
LinkType newLink = Invalid;
if(z < depth - 1 && GetLink(x,y,z+1) != Invalid){
newLink = PositiveZ;
@ -308,21 +308,21 @@ namespace spades {
}else if(z > 0 && GetLink(x,y,z-1) != Invalid){
newLink = NegativeZ;
}
if(newLink != Invalid){
SetLink(x, y, z, newLink);
queue.Push(pos);
}
}
while(!queue.IsEmpty()){
CellPos p = queue.Front();
queue.Shift();
int x = p.x, y = p.y, z = p.z;
LinkType thisLink = GetLink(x,y,z);
if(p.x > 0 && m->IsSolid(x-1,y,z) && GetLink(x-1,y,z) == Invalid &&
thisLink != NegativeX){
SetLink(x-1, y, z, PositiveX);
@ -354,10 +354,10 @@ namespace spades {
queue.Push(CellPos(x, y, z+1));
}
}
std::vector<CellPos> floatingBlocks;
floatingBlocks.reserve(unlinkedCells.size());
for(size_t i = 0; i < unlinkedCells.size(); i++){
const CellPos& p = unlinkedCells[i];
if(!m->IsSolid(p.x, p.y, p.z))
@ -366,7 +366,7 @@ namespace spades {
floatingBlocks.push_back(p);
}
}
return floatingBlocks;
}
}

View File

@ -37,115 +37,115 @@ namespace spades {
#endif
};
MumbleLink::MumbleLink() :
metre_per_block(0.63),
MumbleLink::MumbleLink() :
metre_per_block(0.63),
mumbleLinkedMemory(nullptr),
priv(new MumbleLinkPrivate())
{}
MumbleLink::~MumbleLink() {
#ifdef WIN32
UnmapViewOfFile(mumbleLinkedMemory);
if (priv->obj != nullptr)
CloseHandle(priv->obj);
#else
munmap(mumbleLinkedMemory, sizeof(*mumbleLinkedMemory));
if (priv->fd > 0)
close(priv->fd);
#endif
}
MumbleLink::~MumbleLink() {
#ifdef WIN32
UnmapViewOfFile(mumbleLinkedMemory);
if (priv->obj != nullptr)
CloseHandle(priv->obj);
#else
munmap(mumbleLinkedMemory, sizeof(*mumbleLinkedMemory));
if (priv->fd > 0)
close(priv->fd);
#endif
}
void MumbleLink::set_mumble_vector3(float mumble_vec[3],
const spades::Vector3 &vec) {
mumble_vec[0] = vec.x;
mumble_vec[1] = vec.z;
mumble_vec[2] = vec.y;
}
void MumbleLink::set_mumble_vector3(float mumble_vec[3],
const spades::Vector3 &vec) {
mumble_vec[0] = vec.x;
mumble_vec[1] = vec.z;
mumble_vec[2] = vec.y;
}
bool MumbleLink::init() {
assert(mumbleLinkedMemory == nullptr);
#ifdef WIN32
priv->obj = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, L"MumbleLink");
if (priv->obj == nullptr)
return false;
bool MumbleLink::init() {
assert(mumbleLinkedMemory == nullptr);
#ifdef WIN32
priv->obj = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, L"MumbleLink");
if (priv->obj == nullptr)
return false;
mumbleLinkedMemory = static_cast<MumbleLinkedMemory *>(MapViewOfFile(
priv->obj, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(*mumbleLinkedMemory)));
mumbleLinkedMemory = static_cast<MumbleLinkedMemory *>(MapViewOfFile(
priv->obj, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(*mumbleLinkedMemory)));
if (mumbleLinkedMemory == nullptr) {
CloseHandle(priv->obj);
priv->obj = nullptr;
return false;
}
#else
std::string name = "/MumbleLink." + std::to_string(getuid());
if (mumbleLinkedMemory == nullptr) {
CloseHandle(priv->obj);
priv->obj = nullptr;
return false;
}
#else
std::string name = "/MumbleLink." + std::to_string(getuid());
priv->fd = shm_open(name.c_str(), O_RDWR, S_IRUSR | S_IWUSR);
priv->fd = shm_open(name.c_str(), O_RDWR, S_IRUSR | S_IWUSR);
if (priv->fd < 0) {
return false;
}
if (priv->fd < 0) {
return false;
}
mumbleLinkedMemory = static_cast<MumbleLinkedMemory *>(
(mmap(nullptr, sizeof(*mumbleLinkedMemory), PROT_READ | PROT_WRITE,
MAP_SHARED, priv->fd, 0)));
mumbleLinkedMemory = static_cast<MumbleLinkedMemory *>(
(mmap(nullptr, sizeof(*mumbleLinkedMemory), PROT_READ | PROT_WRITE,
MAP_SHARED, priv->fd, 0)));
if (mumbleLinkedMemory == MAP_FAILED) {
mumbleLinkedMemory = nullptr;
return false;
}
#endif
return true;
}
if (mumbleLinkedMemory == MAP_FAILED) {
mumbleLinkedMemory = nullptr;
return false;
}
#endif
return true;
}
void MumbleLink::setContext(const std::string &context) {
if (mumbleLinkedMemory == nullptr)
return;
size_t len(std::min(256, static_cast<int>(context.size())));
std::memcpy(mumbleLinkedMemory->context, context.c_str(), len);
mumbleLinkedMemory->context_len = len;
}
void MumbleLink::setContext(const std::string &context) {
if (mumbleLinkedMemory == nullptr)
return;
size_t len(std::min(256, static_cast<int>(context.size())));
std::memcpy(mumbleLinkedMemory->context, context.c_str(), len);
mumbleLinkedMemory->context_len = len;
}
void MumbleLink::setIdentity(const std::string &identity) {
if (mumbleLinkedMemory == nullptr)
return;
std::wcsncpy(mumbleLinkedMemory->identity,
std::wstring(identity.begin(), identity.end()).c_str(), 256);
}
void MumbleLink::setIdentity(const std::string &identity) {
if (mumbleLinkedMemory == nullptr)
return;
std::wcsncpy(mumbleLinkedMemory->identity,
std::wstring(identity.begin(), identity.end()).c_str(), 256);
}
void MumbleLink::update(spades::client::Player *player) {
if (mumbleLinkedMemory == nullptr || player == nullptr)
return;
void MumbleLink::update(spades::client::Player *player) {
if (mumbleLinkedMemory == nullptr || player == nullptr)
return;
if (mumbleLinkedMemory->uiVersion != 2) {
wcsncpy(mumbleLinkedMemory->name, L"OpenSpades", 256);
wcsncpy(mumbleLinkedMemory->description, L"OpenSpades Link plugin.", 2048);
mumbleLinkedMemory->uiVersion = 2;
}
mumbleLinkedMemory->uiTick++;
if (mumbleLinkedMemory->uiVersion != 2) {
wcsncpy(mumbleLinkedMemory->name, L"OpenSpades", 256);
wcsncpy(mumbleLinkedMemory->description, L"OpenSpades Link plugin.", 2048);
mumbleLinkedMemory->uiVersion = 2;
}
mumbleLinkedMemory->uiTick++;
// Left handed coordinate system.
// X positive towards "right".
// Y positive towards "up".
// Z positive towards "front".
//
// 1 unit = 1 meter
// Left handed coordinate system.
// X positive towards "right".
// Y positive towards "up".
// Z positive towards "front".
//
// 1 unit = 1 meter
// Unit vector pointing out of the avatar's eyes aka "At"-vector.
set_mumble_vector3(mumbleLinkedMemory->fAvatarFront, player->GetFront());
// Unit vector pointing out of the avatar's eyes aka "At"-vector.
set_mumble_vector3(mumbleLinkedMemory->fAvatarFront, player->GetFront());
// Unit vector pointing out of the top of the avatar's head aka "Up"-vector
// (here Top points straight up).
set_mumble_vector3(mumbleLinkedMemory->fAvatarTop, player->GetUp());
// Unit vector pointing out of the top of the avatar's head aka "Up"-vector
// (here Top points straight up).
set_mumble_vector3(mumbleLinkedMemory->fAvatarTop, player->GetUp());
// Position of the avatar (here standing slightly off the origin)
set_mumble_vector3(mumbleLinkedMemory->fAvatarPosition,
player->GetPosition() * metre_per_block);
// Position of the avatar (here standing slightly off the origin)
set_mumble_vector3(mumbleLinkedMemory->fAvatarPosition,
player->GetPosition() * metre_per_block);
// Same as avatar but for the camera.
set_mumble_vector3(mumbleLinkedMemory->fCameraPosition,
player->GetPosition() * metre_per_block);
set_mumble_vector3(mumbleLinkedMemory->fCameraFront, player->GetFront());
set_mumble_vector3(mumbleLinkedMemory->fCameraTop, player->GetUp());
}
// Same as avatar but for the camera.
set_mumble_vector3(mumbleLinkedMemory->fCameraPosition,
player->GetPosition() * metre_per_block);
set_mumble_vector3(mumbleLinkedMemory->fCameraFront, player->GetFront());
set_mumble_vector3(mumbleLinkedMemory->fCameraTop, player->GetUp());
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +1,21 @@
/*
Copyright (c) 2013 yvt
This file is part of OpenSpades.
OpenSpades is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenSpades is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
*/
#include <OpenSpades.h>
@ -50,39 +50,39 @@ DEFINE_SPADES_SETTING(core_numDispatchQueueThreads, "auto");
static int GetNumCores() {
#ifdef WIN32
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
return sysinfo.dwNumberOfProcessors;
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
return sysinfo.dwNumberOfProcessors;
#elif defined(__APPLE__)
int nm[2];
size_t len = 4;
uint32_t count;
nm[0] = CTL_HW; nm[1] = HW_AVAILCPU;
sysctl(nm, 2, &count, &len, NULL, 0);
if(count < 1) {
nm[1] = HW_NCPU;
sysctl(nm, 2, &count, &len, NULL, 0);
if(count < 1) { count = 1; }
}
return count;
int nm[2];
size_t len = 4;
uint32_t count;
nm[0] = CTL_HW; nm[1] = HW_AVAILCPU;
sysctl(nm, 2, &count, &len, NULL, 0);
if(count < 1) {
nm[1] = HW_NCPU;
sysctl(nm, 2, &count, &len, NULL, 0);
if(count < 1) { count = 1; }
}
return count;
#elif defined(__linux__)
return get_nprocs();
return get_nprocs();
#else
return sysconf(_SC_NPROCESSORS_ONLN);
return sysconf(_SC_NPROCESSORS_ONLN);
#endif
}
namespace spades {
struct SyncQueueEntry{
SDL_cond *doneCond;
SDL_mutex *doneMutex;
ConcurrentDispatch *dispatch;
volatile bool done;
volatile bool released;
SyncQueueEntry(ConcurrentDispatch *disp):
doneCond(SDL_CreateCond()),
doneMutex(SDL_CreateMutex()),
@ -98,7 +98,7 @@ namespace spades {
delete dispatch;
}
}
void Done() {
SDL_LockMutex(doneMutex);
done = true;
@ -109,7 +109,7 @@ namespace spades {
}
SDL_UnlockMutex(doneMutex);
}
void Release() {
SDL_LockMutex(doneMutex);
released = true;
@ -119,7 +119,7 @@ namespace spades {
}
SDL_UnlockMutex(doneMutex);
}
void Join(){
SDL_LockMutex(doneMutex);
while(!done){
@ -128,10 +128,10 @@ namespace spades {
SDL_UnlockMutex(doneMutex);
}
};
class SynchronizedQueue {
std::list<SyncQueueEntry *> entries;
SDL_cond *pushCond;
SDL_mutex *pushMutex;
public:
@ -143,7 +143,7 @@ namespace spades {
SDL_DestroyMutex(pushMutex);
SDL_DestroyCond(pushCond);
}
void Push(SyncQueueEntry * entry) {
SDL_LockMutex(pushMutex);
try{
@ -155,20 +155,20 @@ namespace spades {
SDL_CondSignal(pushCond);
SDL_UnlockMutex(pushMutex);
}
SyncQueueEntry *Wait() {
SDL_LockMutex(pushMutex);
while(entries.empty()){
SDL_CondWait(pushCond, pushMutex);
}
SyncQueueEntry *ent = entries.front();
entries.pop_front();
SDL_UnlockMutex(pushMutex);
return ent;
}
SyncQueueEntry *Poll(){
SDL_LockMutex(pushMutex);
if(!entries.empty()){
@ -181,11 +181,11 @@ namespace spades {
return NULL;
}
};
static SynchronizedQueue globalQueue;
static AutoDeletedThreadLocalStorage<DispatchQueue> threadQueue("threadDispatchQueue");
static DispatchQueue *sdlQueue = NULL;
DispatchQueue::DispatchQueue(){
SPADES_MARK_FUNCTION();
internal = new SynchronizedQueue();
@ -194,7 +194,7 @@ namespace spades {
SPADES_MARK_FUNCTION();
delete internal;
}
DispatchQueue *DispatchQueue::GetThreadQueue() {
SPADES_MARK_FUNCTION();
DispatchQueue *q = threadQueue;
@ -204,7 +204,7 @@ namespace spades {
}
return q;
}
void DispatchQueue::ProcessQueue() {
SPADES_MARK_FUNCTION();
SyncQueueEntry *ent;
@ -213,19 +213,19 @@ namespace spades {
}
Thread::CleanupExitedThreads();
}
void DispatchQueue::EnterEventLoop() throw() {
while(true){
SyncQueueEntry *ent = internal->Wait();
ent->dispatch->ExecuteProtected();
}
}
void DispatchQueue::MarkSDLVideoThread() {
sdlQueue = this;
}
class DispatchThread: public Thread{
public:
virtual void Run() throw() {
@ -236,9 +236,9 @@ namespace spades {
}
}
};
static std::vector<DispatchThread *> threads;
ConcurrentDispatch::ConcurrentDispatch():
entry(NULL), runnable(NULL){
SPADES_MARK_FUNCTION();
@ -247,12 +247,12 @@ namespace spades {
entry(NULL),name(name), runnable(NULL){
SPADES_MARK_FUNCTION();
}
ConcurrentDispatch::~ConcurrentDispatch(){
SPADES_MARK_FUNCTION();
Join();
}
void ConcurrentDispatch::Execute() {
SPADES_MARK_FUNCTION();
SyncQueueEntry *ent = entry;
@ -267,7 +267,7 @@ namespace spades {
}
ent->Done();
}
void ConcurrentDispatch::ExecuteProtected() throw() {
try{
Execute();
@ -279,7 +279,7 @@ namespace spades {
fprintf(stderr, "(no information provided)\n");
}
}
void ConcurrentDispatch::Start() {
SPADES_MARK_FUNCTION();
if(entry){
@ -302,7 +302,7 @@ namespace spades {
globalQueue.Push(entry);
}
}
void ConcurrentDispatch::StartOn(DispatchQueue *queue) {
SPADES_MARK_FUNCTION();
if(entry){
@ -310,7 +310,7 @@ namespace spades {
}else{
entry = new SyncQueueEntry(this);
queue->internal->Push(entry);
if(queue == sdlQueue) {
SDL_Event evt;
memset(&evt, 0, sizeof(evt));
@ -319,7 +319,7 @@ namespace spades {
}
}
}
void ConcurrentDispatch::Join() {
SPADES_MARK_FUNCTION();
if(!entry){
@ -329,7 +329,7 @@ namespace spades {
entry = NULL;
}
}
void ConcurrentDispatch::Release(){
SPADES_MARK_FUNCTION();
if(entry){
@ -337,7 +337,7 @@ namespace spades {
ent->Release();
}
}
void ConcurrentDispatch::Run(){
if(runnable)
runnable->Run();

View File

@ -1,21 +1,21 @@
/*
Copyright (c) 2013 yvt
This file is part of OpenSpades.
OpenSpades is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenSpades is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
*/
#include "FileManager.h"
@ -32,20 +32,20 @@ namespace spades {
SPADES_MARK_FUNCTION();
if(!fn) SPInvalidArgument("fn");
if(fn[0] == 0) SPFileNotFound(fn);
// check each file systems
// check each file systems
for(auto *fs: g_fileSystems){
if(fs->FileExists(fn))
return fs->OpenForReading(fn);
}
// check weak files, too
auto weak_fn = std::string(fn) + ".weak";
for(auto *fs: g_fileSystems){
if(fs->FileExists(weak_fn.c_str()))
return fs->OpenForReading(weak_fn.c_str());
}
// check weak files, too
auto weak_fn = std::string(fn) + ".weak";
for(auto *fs: g_fileSystems){
if(fs->FileExists(weak_fn.c_str()))
return fs->OpenForReading(weak_fn.c_str());
}
SPFileNotFound(fn);
}
IStream *FileManager::OpenForWriting(const char *fn) {
@ -56,9 +56,9 @@ namespace spades {
if(fs->FileExists(fn))
return fs->OpenForWriting(fn);
}
// FIXME: handling of weak files
// FIXME: handling of weak files
// create file
for(auto *fs: g_fileSystems){
try{
@ -66,50 +66,50 @@ namespace spades {
}catch(...){
}
}
SPRaise("No filesystem is writable");
}
bool FileManager::FileExists(const char *fn) {
SPADES_MARK_FUNCTION();
if(!fn) SPInvalidArgument("fn");
for(auto *fs: g_fileSystems){
if(fs->FileExists(fn))
return true;
}
// check weak files, too
auto weak_fn = std::string(fn) + ".weak";
for(auto *fs: g_fileSystems){
if(fs->FileExists(weak_fn.c_str()))
return true;
}
}
// check weak files, too
auto weak_fn = std::string(fn) + ".weak";
for(auto *fs: g_fileSystems){
if(fs->FileExists(weak_fn.c_str()))
return true;
}
return false;
}
void FileManager::AddFileSystem(spades::IFileSystem *fs){
SPADES_MARK_FUNCTION();
AppendFileSystem(fs);
}
void FileManager::AppendFileSystem(spades::IFileSystem *fs){
SPADES_MARK_FUNCTION();
if(!fs) SPInvalidArgument("fs");
g_fileSystems.push_back(fs);
}
void FileManager::PrependFileSystem(spades::IFileSystem *fs){
SPADES_MARK_FUNCTION();
if(!fs) SPInvalidArgument("fs");
g_fileSystems.push_front(fs);
}
std::string FileManager::ReadAllBytes(const char *fn) {
SPADES_MARK_FUNCTION();
IStream *stream = OpenForReading(fn);
try{
std::string ret = stream->ReadAllBytes();
@ -120,23 +120,23 @@ namespace spades {
throw;
}
}
std::vector<std::string> FileManager::EnumFiles(const char *path) {
std::vector<std::string> list;
std::set<std::string> set;
if(!path) SPInvalidArgument("path");
for(auto *fs: g_fileSystems){
std::vector<std::string> l = fs->EnumFiles(path);
for(size_t i = 0; i < l.size(); i++)
set.insert(l[i]);
}
for(auto& s: set)
list.push_back(s);
return list;
}
}

View File

@ -1,21 +1,21 @@
/*
Copyright (c) 2013 yvt
This file is part of OpenSpades.
OpenSpades is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenSpades is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptManager.h"
@ -25,28 +25,28 @@
#include <unordered_map>
namespace spades {
namespace
{
ThreadLocalStorage<bool> writeAllowed;
// SettingItemDescriptor supplied to ItemHandle must have the static storage duration
std::unordered_map<std::string, const SettingItemDescriptor *>
settingItemDescriptors;
const SettingItemDescriptor *MakeSettingItemDescriptor
(const std::string &name, const std::string &defaultValue)
{
auto it = settingItemDescriptors.find(name);
if (it != settingItemDescriptors.end()) {
return it->second;
}
auto *descriptor = new SettingItemDescriptor(defaultValue, SettingItemFlags::None);
settingItemDescriptors.insert(make_pair(name, descriptor));
return descriptor;
}
}
namespace
{
ThreadLocalStorage<bool> writeAllowed;
// SettingItemDescriptor supplied to ItemHandle must have the static storage duration
std::unordered_map<std::string, const SettingItemDescriptor *>
settingItemDescriptors;
const SettingItemDescriptor *MakeSettingItemDescriptor
(const std::string &name, const std::string &defaultValue)
{
auto it = settingItemDescriptors.find(name);
if (it != settingItemDescriptors.end()) {
return it->second;
}
auto *descriptor = new SettingItemDescriptor(defaultValue, SettingItemFlags::None);
settingItemDescriptors.insert(make_pair(name, descriptor));
return descriptor;
}
}
void MaskConfigUpdateByScript(bool disabled)
{
if (!writeAllowed) {
@ -54,32 +54,32 @@ namespace spades {
}
*writeAllowed = !disabled;
}
class ConfigRegistrar: public ScriptObjectRegistrar {
public:
ConfigRegistrar():
ScriptObjectRegistrar("Config") {}
class ConfigItem: public RefCountedObject {
Settings::ItemHandle handle;
public:
ConfigItem(const std::string& name, const std::string& defaultValue):
handle(name, MakeSettingItemDescriptor(name, defaultValue)){
}
ConfigItem(const std::string& name):
handle(name, nullptr){
}
public:
ConfigItem(const std::string& name, const std::string& defaultValue):
handle(name, MakeSettingItemDescriptor(name, defaultValue)){
}
ConfigItem(const std::string& name):
handle(name, nullptr){
}
static ConfigItem *Construct(const std::string& name, const std::string& defaultValue) {
return new ConfigItem(name, defaultValue);
}
static ConfigItem *Construct(const std::string& name) {
return new ConfigItem(name);
}
ConfigItem *operator =(float fv) {
if (!writeAllowed || !*writeAllowed) {
return this;
@ -92,7 +92,7 @@ namespace spades {
if (!writeAllowed || !*writeAllowed) {
return this;
}
handle = v;
AddRef();
return this;
@ -101,7 +101,7 @@ namespace spades {
if (!writeAllowed || !*writeAllowed) {
return this;
}
handle = v;
AddRef();
return this;
@ -128,12 +128,12 @@ namespace spades {
return (std::string)handle;
}
};
static CScriptArray *GetAllConfigNames() {
auto *ctx = asGetActiveContext();
auto *engine = ctx->GetEngine();
auto *arrayType = engine->GetTypeInfoByDecl("array<string>");
auto *array = CScriptArray::Create(arrayType);
auto *array = CScriptArray::Create(arrayType);
auto names = Settings::GetInstance()->GetAllItemNames();
array->Resize(static_cast<asUINT>(names.size()));
for(std::size_t i = 0; i < names.size(); i++) {
@ -141,7 +141,7 @@ namespace spades {
}
return array;
}
virtual void Register(ScriptManager *manager, Phase phase) {
asIScriptEngine *eng = manager->GetEngine();
int r;
@ -222,7 +222,7 @@ namespace spades {
asMETHOD(ConfigItem, GetStringValue),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterGlobalFunction("array<string>@ GetAllConfigNames()",
asFUNCTION(GetAllConfigNames),
asCALL_CDECL);
@ -233,8 +233,8 @@ namespace spades {
}
}
};
static ConfigRegistrar registrar;
}

View File

@ -1,21 +1,21 @@
/*
Copyright (c) 2013 yvt
This file is part of OpenSpades.
OpenSpades is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenSpades is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptManager.h"
@ -46,45 +46,45 @@ namespace spades {
ArrayType *obj = new ArrayType(initialSize);
asGetActiveContext()->GetEngine()->NotifyGarbageCollectorOfNewObject(obj, scrType);
return obj;
}
static ArrayType *Factory3(asUINT initialSize, T initialValue) {
if(initialSize > 1024 * 1024 * 256) {
asGetActiveContext()->SetException("Too many array elements");
return NULL;
}
ArrayType *obj = new ArrayType(initialSize, initialValue);
asGetActiveContext()->GetEngine()->NotifyGarbageCollectorOfNewObject(obj, scrType);
return obj;
}
static ArrayType *Factory4(void *initList) {
asUINT length = *reinterpret_cast<const asUINT *>(initList);
if(length > 1024 * 1024 * 256) {
asGetActiveContext()->SetException("Too many array elements");
}
ArrayType *obj = new ArrayType(initList);
asGetActiveContext()->GetEngine()->NotifyGarbageCollectorOfNewObject(obj, scrType);
return obj;
}
}
static ArrayType *Factory3(asUINT initialSize, T initialValue) {
if(initialSize > 1024 * 1024 * 256) {
asGetActiveContext()->SetException("Too many array elements");
return NULL;
}
ArrayType *obj = new ArrayType(initialSize, initialValue);
asGetActiveContext()->GetEngine()->NotifyGarbageCollectorOfNewObject(obj, scrType);
return obj;
}
static ArrayType *Factory4(void *initList) {
asUINT length = *reinterpret_cast<const asUINT *>(initList);
if(length > 1024 * 1024 * 256) {
asGetActiveContext()->SetException("Too many array elements");
}
ArrayType *obj = new ArrayType(initList);
asGetActiveContext()->GetEngine()->NotifyGarbageCollectorOfNewObject(obj, scrType);
return obj;
}
PrimitiveArray(asUINT initialSize = 0) {
inner.resize(initialSize);
}
PrimitiveArray(asUINT initialSize, T initialValue) {
inner.resize(initialSize, initialValue);
}
PrimitiveArray(void *initList) {
asUINT length = *reinterpret_cast<const asUINT *>(initList);
inner.resize(length);
memcpy(inner.data(), reinterpret_cast<const asUINT *>(initList) + 1, inner.size() * sizeof(T));
}
}
PrimitiveArray(asUINT initialSize, T initialValue) {
inner.resize(initialSize, initialValue);
}
PrimitiveArray(void *initList) {
asUINT length = *reinterpret_cast<const asUINT *>(initList);
inner.resize(length);
memcpy(inner.data(), reinterpret_cast<const asUINT *>(initList) + 1, inner.size() * sizeof(T));
}
void AddRef() {
refCount &= 0x7fffffff;
asAtomicInc(refCount);
}
void Release() {
refCount &= 0x7fffffff;
if(asAtomicDec(refCount) <= 0)
delete this;
}
@ -99,7 +99,7 @@ namespace spades {
}
void EnumReferences(asIScriptEngine *eng) {}
void ReleaseAllReferences(asIScriptEngine *eng){}
T& At(asUINT index) {
if(index >= inner.size()){
asGetActiveContext()->SetException("Index out of bounds");
@ -160,7 +160,7 @@ namespace spades {
inner.reserve((size_t)siz);
}
}
void SortAsc(asUINT index, asUINT count){
if(count <= 0) return;
if(index + count > inner.size()){
@ -186,24 +186,24 @@ namespace spades {
void SortDesc() {
SortDesc(0, GetSize());
}
void Reverse() {
std::reverse(inner.begin(), inner.end());
}
int Find(const T& val) const {
typename std::vector<T>::const_iterator it = std::find(inner.begin(), inner.end(), val);
if(it == inner.end()) return -1;
return static_cast<int> (it - inner.begin());
}
int Find(asUINT ind, const T& val) const {
if(ind >= GetSize()) return -1;
typename std::vector<T>::const_iterator it = std::find(inner.begin() + ind, inner.end(), val);
if(it == inner.end()) return -1;
return static_cast<int> (it - inner.begin());
}
bool operator ==(const ArrayType& array) const {
if(this == &array)
return true;
@ -215,13 +215,13 @@ namespace spades {
return false;
return true;
}
bool IsEmpty() const {
return inner.empty();
}
};
template<typename T>
class PrimitiveArrayRegistrar: public ScriptObjectRegistrar {
std::string typeName;
@ -304,154 +304,154 @@ namespace spades {
F("void f(int& in)"),
asMETHOD(ArrayType, ReleaseAllReferences), asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("%s& opIndex(uint)"),
asMETHODPR(ArrayType, At, (asUINT), T&),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("const %s& opIndex(uint) const"),
asMETHODPR(ArrayType, At, (asUINT) const, const T&),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("array<%s> &opAssign(const array<%s>&)"),
asMETHODPR(ArrayType, operator =, (const ArrayType&), ArrayType&),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("void insertAt(uint, const %s& in)"),
asMETHODPR(ArrayType, InsertAt, (asUINT, const T&), void),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("void removeAt(uint)"),
asMETHOD(ArrayType, RemoveAt),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("void insertLast(const %s& in)"),
asMETHOD(ArrayType, InsertLast),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("void removeLast()"),
asMETHOD(ArrayType, RemoveLast),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("uint length()"),
asMETHOD(ArrayType, GetSize),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("void resize(uint)"),
asMETHOD(ArrayType, Resize),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("void reserve(uint)"),
asMETHOD(ArrayType, Reserve),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("void sortAsc()"),
asMETHODPR(ArrayType, SortAsc, (), void),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("void sortAsc(uint, uint)"),
asMETHODPR(ArrayType, SortAsc, (asUINT, asUINT), void),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("void sortDesc()"),
asMETHODPR(ArrayType, SortDesc, (), void),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("void sortDesc(uint, uint)"),
asMETHODPR(ArrayType, SortDesc, (asUINT, asUINT), void),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("int find(const %s& in) const"),
asMETHODPR(ArrayType, Find, (const T&) const, int),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("int find(uint, const %s& in) const"),
asMETHODPR(ArrayType, Find, (asUINT, const T&) const, int),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("bool opEquals(const array<%s>&) const"),
asMETHODPR(ArrayType, operator ==, (const ArrayType&) const, bool),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("uint get_length()"),
asMETHOD(ArrayType, GetSize),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("void set_length(uint)"),
asMETHOD(ArrayType, Resize),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("bool isEmpty()"),
asMETHOD(ArrayType, IsEmpty),
asCALL_THISCALL);
manager->CheckError(r);
// STL name
r = eng->RegisterObjectMethod(ATN(),
F("uint size()"),
asMETHOD(ArrayType, GetSize),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("bool empty()"),
asMETHOD(ArrayType, IsEmpty),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("void push_back(const %s& in)"),
asMETHOD(ArrayType, InsertLast),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("void pop_back()"),
asMETHOD(ArrayType, RemoveLast),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod(ATN(),
F("void erase(uint)"),
asMETHOD(ArrayType, RemoveAt),
@ -474,5 +474,5 @@ namespace spades {
static PrimitiveArrayRegistrar<uint64_t> uint64ArrayRegistrar("uint64");
static PrimitiveArrayRegistrar<float> floatArrayRegistrar("float");
static PrimitiveArrayRegistrar<double> doubleArrayRegistrar("double");
}

File diff suppressed because it is too large Load Diff