commit 2f0494edc9017598153f58f959ca4be6d4815bfa Author: Alex Yatskov Date: Tue Oct 21 13:54:42 2014 +0900 Initial commit diff --git a/Actor.cpp b/Actor.cpp new file mode 100644 index 0000000..e747400 --- /dev/null +++ b/Actor.cpp @@ -0,0 +1,280 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "Pch.h" +#include "Actor.h" +#include "ActorProperty.h" +#include "ActorManager.h" +#include "Surface.h" + +#define ACTOR_ID_FROM_NAME(name) (Token(name) | ~0x7fffffff) +#define ACTOR_ID_FROM_INC(inc) (Token(inc) & 0x7fffffff) + +Actor::Actor(const char* alias, const char* name) : + m_owner(NULL), + m_dynamic(false), + m_layer(ACTOR_LAYER_COUNT) +{ + if (alias != NULL) + { + m_alias = alias; + } + + SetName(name); +} + +void Actor::Render(const boost::shared_ptr& target) +{ + for (int i = 0; i < ARRAY_SIZE(m_properties); ++i) + { + if (m_properties[i]) + { + m_properties[i]->Render(target); + } + } + + if (m_owner->AreShapesVisible()) + { + RenderShapes(target); + } +} + +void Actor::Update(float elapsed) +{ + for (int i = 0; i < ARRAY_SIZE(m_properties); ++i) + { + if (m_properties[i]) + { + m_properties[i]->Update(elapsed); + } + } +} + +void Actor::SetPosition(const Vector2i& position) +{ + const Vector2f positionFloat(static_cast(position.x), static_cast(position.y)); + SetPositionSoft(positionFloat); +} + +Vector2i Actor::GetPosition() const +{ + const Vector2i positionInt(static_cast(floorf(m_position.x + 0.5f)), static_cast(floorf(m_position.y + 0.5f))); + return positionInt; +} + +void Actor::SetPositionSoft(const Vector2f& position) +{ + const Vector2i positionInt(static_cast(floorf(position.x + 0.5f)), static_cast(floorf(position.y + 0.5f))); + + if (positionInt != GetPosition() && m_owner != NULL) + { + m_owner->UpdateActorPosition(GetId(), GetPosition(), positionInt); + } + + m_position = position; +} + +Vector2f Actor::GetPositionSoft() const +{ + return m_position; +} + +void Actor::SetLayer(ActorLayer layer) +{ + m_layer = layer; +} + +ActorLayer Actor::GetLayer() const +{ + return m_layer; +} + +void Actor::SetDynamic(bool dynamic) +{ + m_dynamic = dynamic; +} + +bool Actor::IsDynamic() const +{ + return m_dynamic; +} + +void Actor::SetId(Token id) +{ + if (id == GetId()) + { + return; + } + + if (m_owner != NULL && GetId().IsValid()) + { + m_owner->UpdateActorId(GetId(), id); + } + + m_id = id; +} + +Token Actor::GetId() const +{ + return m_id; +} + +const char* Actor::GetAlias() const +{ + return m_alias.c_str(); +} + +void Actor::SetName(const char* name) +{ + if (name == NULL || strlen(name) == 0) + { + SetId(ACTOR_ID_FROM_INC(RegisterId())); + m_name.clear(); + } + else + { + SetId(ACTOR_ID_FROM_NAME(name)); + m_name = name; + } +} + +const char* Actor::GetName() const +{ + return m_name.c_str(); +} + +void Actor::SetOwner(ActorManager* owner) +{ + m_owner = owner; +} + +const ActorManager* Actor::GetOwner() const +{ + return m_owner; +} + +ActorManager* Actor::GetOwner() +{ + return m_owner; +} + +void Actor::GetShape(ActorShapeType type, int* data, Vector2i* position, Vector2i* size) const +{ + ASSERT(type < ARRAY_SIZE(m_shapes)); + *data = m_shapes[type].data; + *position = m_shapes[type].position; + *size = m_shapes[type].size; +} + +void Actor::SetShape(ActorShapeType type, int data, const Vector2i& position, const Vector2i& size) +{ + ASSERT(type < ARRAY_SIZE(m_shapes)); + m_shapes[type].data = data; + m_shapes[type].position = position; + m_shapes[type].size = size; +} + +ActorShape Actor::GetShape(ActorShapeType type) const +{ + ASSERT(type < ARRAY_SIZE(m_shapes)); + return m_shapes[type]; +} + +void Actor::SetShape(ActorShapeType type, const ActorShape& shape) +{ + ASSERT(type < ARRAY_SIZE(m_shapes)); + m_shapes[type] = shape; +} + +void Actor::EnableShape(ActorShapeType type) +{ + ASSERT(type < ARRAY_SIZE(m_shapes)); + m_shapes[type].enabled = true; +} + +void Actor::DisableShape(ActorShapeType type) +{ + ASSERT(type < ARRAY_SIZE(m_shapes)); + m_shapes[type].enabled = false; +} + +bool Actor::IsShapeEnabled(ActorShapeType type) const +{ + ASSERT(type < ARRAY_SIZE(m_shapes)); + return m_shapes[type].enabled; +} + +Token Actor::RegisterId() +{ + static int s_idPool = 0; + Token token(s_idPool); + do + { + token = Token(++s_idPool); + } + while (!token); + return token; +} + +void Actor::RenderShapes(const boost::shared_ptr& target) +{ + Vector2i maxShapeSize(0, 0); + for (int i = 0; i < ARRAY_SIZE(m_shapes); ++i) + { + const ActorShape& shape = m_shapes[i]; + if (!shape.enabled) + { + continue; + } + + maxShapeSize.x = MAX(maxShapeSize.x, shape.size.x); + maxShapeSize.y = MAX(maxShapeSize.y, shape.size.y); + } + + if (maxShapeSize.x == 0 || maxShapeSize.y == 0) + { + return; + } + + if (!m_shapeSurface || m_shapeSurface->GetSize().x < maxShapeSize.x || m_shapeSurface->GetSize().y < maxShapeSize.y) + { + m_shapeSurface = System::CreateSurface(maxShapeSize, COLOR_MODE_RGBA_8888); + } + + static const Color4b s_shapeColors[] = + { + Color4b(0x00, 0x00, 0xc0, 0x60), // ACTOR_SHAPE_TYPE_COLLISION_SOLID + Color4b(0x00, 0xc0, 0x00, 0x60) // ACTOR_SHAPE_TYPE_COLLISION_INTERACT + }; + + BOOST_STATIC_ASSERT(ARRAY_SIZE(s_shapeColors) == ACTOR_SHAPE_TYPE_COUNT); + + for (int i = 0; i < ARRAY_SIZE(m_shapes); ++i) + { + const ActorShape& shape = m_shapes[i]; + if (!shape.enabled) + { + continue; + } + + target->PushState(); + target->SetTranslationRelative(shape.position); + m_shapeSurface->Clear(s_shapeColors[i]); + m_shapeSurface->Blit(target, Vector2i(0, 0), shape.size); + target->PopState(); + } +} diff --git a/Actor.h b/Actor.h new file mode 100644 index 0000000..95884a2 --- /dev/null +++ b/Actor.h @@ -0,0 +1,111 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +class ActorManager; +class ActorProperty; + +class Actor : private boost::noncopyable +{ +public: + Actor(const char* alias, const char* name); + + void Render(const boost::shared_ptr& target); + void Update(float elapsed); + + void SetPosition(const Vector2i& position); + Vector2i GetPosition() const; + void SetPositionSoft(const Vector2f& position); + Vector2f GetPositionSoft() const; + void SetLayer(ActorLayer layer); + ActorLayer GetLayer() const; + void SetDynamic(bool dynamic); + bool IsDynamic() const; + + void SetName(const char* name); + const char* GetName() const; + Token GetId() const; + const char* GetAlias() const; + + template + boost::weak_ptr AddProperty() + { + ASSERT(T::GetStaticType() < ARRAY_SIZE(m_properties)); + boost::shared_ptr& property = m_properties[T::GetStaticType()]; + if (!property) + { + property = boost::shared_ptr(new T(this)); + } + return GetProperty(); + } + + template + void RemoveProperty() + { + ASSERT(T::GetStaticType() < ARRAY_SIZE(m_properties)); + m_properties[T::GetStaticType()].reset(); + } + + template + boost::weak_ptr GetProperty() const + { + ASSERT(T::GetStaticType() < ARRAY_SIZE(m_properties)); + return boost::static_pointer_cast(m_properties[T::GetStaticType()]); + } + + template + boost::weak_ptr GetProperty() + { + ASSERT(T::GetStaticType() < ARRAY_SIZE(m_properties)); + return boost::static_pointer_cast(m_properties[T::GetStaticType()]); + } + + bool HasProperty(ActorPropertyType property) const + { + ASSERT(property < ARRAY_SIZE(m_properties)); + return m_properties[property]; + } + + void SetOwner(ActorManager* owner); + const ActorManager* GetOwner() const; + ActorManager* GetOwner(); + + void GetShape(ActorShapeType type, int* data, Vector2i* position, Vector2i* size) const; + void SetShape(ActorShapeType type, int data, const Vector2i& position, const Vector2i& size); + ActorShape GetShape(ActorShapeType type) const; + void SetShape(ActorShapeType type, const ActorShape& shape); + void EnableShape(ActorShapeType type); + void DisableShape(ActorShapeType type); + bool IsShapeEnabled(ActorShapeType type) const; + +private: + void RenderShapes(const boost::shared_ptr& target); + static Token RegisterId(); + void SetId(Token id); + + boost::shared_ptr m_properties[ACTOR_PROPERTY_TYPE_COUNT]; + ActorShape m_shapes[ACTOR_SHAPE_TYPE_COUNT]; + ActorManager* m_owner; + bool m_dynamic; + ActorLayer m_layer; + Vector2f m_position; + std::string m_alias; + std::string m_name; + Token m_id; + boost::shared_ptr m_shapeSurface; +}; diff --git a/ActorManager.cpp b/ActorManager.cpp new file mode 100644 index 0000000..f2e8ffc --- /dev/null +++ b/ActorManager.cpp @@ -0,0 +1,320 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "Pch.h" +#include "ActorManager.h" +#include "Actor.h" +#include "ActorPropertyAnimation.h" +#include "ActorPropertySprite.h" +#include "Surface.h" + +ActorManager::ActorManager() : + m_layers(static_cast(-1)), + m_renderShapes(false) +{ +} + +void ActorManager::Render(const boost::shared_ptr& target, const Rect4i& bounds) +{ + for (size_t i = 0; i < m_actorCache.size(); ++i) + { + const boost::shared_ptr actor = m_actorCache[i]; + if (IsLayerVisible(actor->GetLayer())) + { + target->SetTranslation(Vector2i(actor->GetPosition().x - bounds.x0, actor->GetPosition().y - bounds.y0)); + actor->Render(target); + } + } +} + +void ActorManager::Update(float elapsed, const Rect4i& bounds) +{ + m_actorCache.clear(); + m_actors.Query(&m_actorCache, bounds + Rect4i(-256, -256, 256, 256)); + std::sort(m_actorCache.begin(), m_actorCache.end(), ActorSorter); + + for (size_t i = 0; i < m_actorCache.size(); ++i) + { + m_actorCache[i]->Update(elapsed); + } +} + +boost::weak_ptr ActorManager::AddActor(const char* actorAlias, const Vector2i& actorPosition, const char* actorName) +{ + do + { + const boost::shared_ptr actor = System::CreateActor(actorAlias, actorName); + if (!actor) + { + break; + } + + actor->SetPosition(actorPosition); + actor->SetOwner(this); + + if (!m_actors.Add(actor, actor->GetId(), actor->GetPosition())) + { + TRACE_ERROR( + boost::format("Cannot add actor %s with id %d at (%f, %f)") % + actorAlias % + actor->GetId() % + actorPosition.x % + actorPosition.y + ); + break; + } + + return actor; + } + while (false); + + return boost::weak_ptr(); +} + +boost::weak_ptr ActorManager::GetActor(Token actorId) const +{ + const boost::shared_ptr* const actor = m_actors.Get(actorId); + return actor == NULL ? boost::weak_ptr() : *actor; +} + +boost::weak_ptr ActorManager::GetActor(Token actorId) +{ + const boost::shared_ptr* const actor = m_actors.Get(actorId); + return actor == NULL ? boost::weak_ptr() : *actor; +} + +boost::weak_ptr ActorManager::GetActor(const char* actorName) const +{ + return GetActor(Token(actorName) | ~0x7fffffff); +} + +boost::weak_ptr ActorManager::GetActor(const char* actorName) +{ + return GetActor(Token(actorName) | ~0x7fffffff); +} + +boost::weak_ptr ActorManager::PickActor(const Vector2i& position, const Vector2i& extents) const +{ + return const_cast(this)->PickActor(position); +} + +boost::weak_ptr ActorManager::PickActor(const Vector2i& position, const Vector2i& extents) +{ + const Rect4i boundsQuery( + position.x - extents.x, + position.y - extents.y, + position.x + extents.x, + position.y + extents.y + ); + + std::vector > actors; + m_actors.Query(&actors, boundsQuery); + std::sort(actors.begin(), actors.end(), ActorSorter); + + for (int i = static_cast(actors.size()) - 1; i >= 0; --i) + { + const boost::shared_ptr actor = actors[i]; + if (!IsLayerVisible(actor->GetLayer())) + { + continue; + } + + const Vector2i actorPosition = actor->GetPosition(); + + if (boost::shared_ptr property = actor->GetProperty().lock()) + { + const Rect4i actorRect( + actorPosition.x, + actorPosition.y, + actorPosition.x + property->GetSize().x, + actorPosition.y + property->GetSize().y + ); + + if (actorRect.Contains(position.x, position.y)) + { + return actor; + } + } + + if (boost::shared_ptr property = actor->GetProperty().lock()) + { + const Rect4i actorRect( + actorPosition.x, + actorPosition.y, + actorPosition.x + property->GetSize().x, + actorPosition.y + property->GetSize().y + ); + + if (actorRect.Contains(position.x, position.y)) + { + return actor; + } + } + + if (AreShapesVisible()) + { + for (int i = 0; i < ACTOR_SHAPE_TYPE_COUNT; ++i) + { + ActorShape actorShape = actor->GetShape(static_cast(i)); + if (!actorShape.enabled) + { + continue; + } + + const Rect4i actorRect( + actorPosition.x + actorShape.position.x, + actorPosition.y + actorShape.position.y, + actorPosition.x + actorShape.position.x + actorShape.size.x, + actorPosition.y + actorShape.position.y + actorShape.size.y + ); + + if (actorRect.Contains(position.x, position.y)) + { + return actor; + } + } + } + } + + return boost::weak_ptr(); +} + +void ActorManager::EnumerateActors(std::vector >* actors) +{ + std::vector > temp; + m_actors.Enumerate(&temp); + for (size_t i = 0; i < temp.size(); ++i) + { + actors->push_back(temp[i]); + } +} + +void ActorManager::EnumerateActors(std::vector >* actors, const Vector2i& position, const Vector2i& extents) +{ + const Rect4i boundsQuery( + position.x - extents.x, + position.y - extents.y, + position.x + extents.x, + position.y + extents.y + ); + + std::vector > boundActors; + m_actors.Query(&boundActors, boundsQuery); + + for (std::vector >::iterator iter = boundActors.begin(); iter != boundActors.end(); ++iter) + { + actors->push_back(*iter); + } +} + +void ActorManager::RemoveActor(Token actorId) +{ + if (!m_actors.Remove(actorId)) + { + TRACE_ERROR(boost::format("Cannot remove actor with id %d") % actorId); + } +} + +void ActorManager::ClearActors() +{ + m_actors.Clear(); +} + +void ActorManager::UpdateActorPosition(Token actorId, const Vector2i& positionOld, const Vector2i& positionNew) +{ + const boost::shared_ptr actor = GetActor(actorId).lock(); + if (actor && !m_actors.Update(actor->GetId(), positionNew)) + { + TRACE_ERROR( + boost::format("Cannot update position for actor %s with id %d from (%f, %f) to (%f, %f)") % actor->GetAlias() % actorId % positionOld.x % positionOld.y % positionNew.x % positionNew.y + ); + } +} + +void ActorManager::UpdateActorId(Token actorIdOld, Token actorIdNew) +{ + if (actorIdOld == actorIdNew) + { + return; + } + + do + { + const boost::shared_ptr* const actor = m_actors.Get(actorIdOld); + if (actor == NULL) + { + break; + } + + const boost::shared_ptr temp = *actor; + + if (!m_actors.Remove(actorIdOld) || !m_actors.Add(temp, actorIdNew, temp->GetPosition())) + { + break; + } + + return; + } + while (false); + + TRACE_ERROR(boost::format("Cannot change actor id from %d to %d") % actorIdOld % actorIdNew); +} + +void ActorManager::ShowLayer(ActorLayer layer) +{ + m_layers |= BIT(layer); +} + +void ActorManager::HideLayer(ActorLayer layer) +{ + m_layers &= ~BIT(layer); +} + +void ActorManager::ShowAllLayers() +{ + m_layers = static_cast(-1); +} + +void ActorManager::HideAllLayers() +{ + m_layers = 0; +} + +void ActorManager::ShowShapes() +{ + m_renderShapes = true; +} + +void ActorManager::HideShapes() +{ + m_renderShapes = false; +} + +bool ActorManager::AreShapesVisible() const +{ + return m_renderShapes; +} + +bool ActorManager::IsLayerVisible(ActorLayer layer) const +{ + return IS_TRUE(m_layers & BIT(layer)); +} + +bool ActorManager::ActorSorter(const boost::shared_ptr& actor1, const boost::shared_ptr& actor2) +{ + return actor1->GetLayer() < actor2->GetLayer() || (actor1->GetLayer() == actor2->GetLayer() && actor1->GetPosition().y < actor2->GetPosition().y); +} diff --git a/ActorManager.h b/ActorManager.h new file mode 100644 index 0000000..71c2d53 --- /dev/null +++ b/ActorManager.h @@ -0,0 +1,60 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +class ActorManager +{ +public: + ActorManager(); + + void Render(const boost::shared_ptr& target, const Rect4i& bounds); + void Update(float elapsed, const Rect4i& bounds); + + boost::weak_ptr AddActor(const char* actorAlias, const Vector2i& actorPosition, const char* actorName); + boost::weak_ptr GetActor(Token actorId) const; + boost::weak_ptr GetActor(Token actorId); + boost::weak_ptr GetActor(const char* actorName) const; + boost::weak_ptr GetActor(const char* actorName); + boost::weak_ptr PickActor(const Vector2i& position, const Vector2i& extents = Vector2i(512, 512)) const; + boost::weak_ptr PickActor(const Vector2i& position, const Vector2i& extents = Vector2i(512, 512)); + void EnumerateActors(std::vector >* actors, const Vector2i& position, const Vector2i& extents = Vector2i(512, 512)); + void EnumerateActors(std::vector >* actors); + void RemoveActor(Token actorId); + void ClearActors(); + + void UpdateActorPosition(Token actorId, const Vector2i& positionOld, const Vector2i& positionNew); + void UpdateActorId(Token actorIdOld, Token actorIdNew); + + bool IsLayerVisible(ActorLayer layer) const; + void ShowLayer(ActorLayer layer); + void HideLayer(ActorLayer layer); + void ShowAllLayers(); + void HideAllLayers(); + + void ShowShapes(); + void HideShapes(); + bool AreShapesVisible() const; + +private: + static bool ActorSorter(const boost::shared_ptr& actor1, const boost::shared_ptr& actor2); + + Grid, Token> m_actors; + std::vector > m_actorCache; + unsigned m_layers; + bool m_renderShapes; +}; diff --git a/ActorManifest.cpp b/ActorManifest.cpp new file mode 100644 index 0000000..b5f4fd8 --- /dev/null +++ b/ActorManifest.cpp @@ -0,0 +1,274 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "Pch.h" +#include "ActorManifest.h" +#include "Actor.h" +#include "ActorPropertyAnimation.h" +#include "ActorPropertyPhysics.h" +#include "ActorPropertyScript.h" +#include "ActorPropertySprite.h" +#include "Surface.h" +#include "Sprite.h" + +bool ActorManifest::LoadManifest(const char* filename) +{ + const boost::shared_ptr buffer = System::LoadFile(filename); + if (!buffer) + { + TRACE_ERROR(boost::format("Cannot load actor manifest %s") % filename); + return false; + } + + TiXmlDocument document; + if (!document.Parse(static_cast(buffer->Get()))) + { + TRACE_ERROR(boost::format("Cannot parse actor manifest %s") % filename); + return false; + } + + const TiXmlElement* rootElement = document.RootElement(); + if (rootElement == NULL || strcmp(rootElement->Value(), "Manifest") != 0) + { + return false; + } + + for (const TiXmlElement* actorElement = rootElement->FirstChildElement(); actorElement != NULL; actorElement = actorElement->NextSiblingElement()) + { + if (strcmp(actorElement->Value(), "Actor") != 0) + { + continue; + } + + const char* alias = actorElement->Attribute("alias"); + if (alias == NULL) + { + TRACE_WARNING("Actor definition is missing required fields"); + continue; + } + + if (m_manifest.find(alias) != m_manifest.end()) + { + TRACE_WARNING(boost::format("Duplicate actor %s") % alias); + continue; + } + + ActorEntry entry; + + const char* thumbnail = actorElement->Attribute("thumbnail"); + if (thumbnail != NULL) + { + entry.thumbnail = thumbnail; + } + + int dynamic = 0; + actorElement->QueryIntAttribute("dynamic", &dynamic); + entry.dynamic = dynamic != 0; + + int layer = ACTOR_LAYER_GROUND1; + actorElement->QueryIntAttribute("layer", &layer); + if (layer < ACTOR_LAYER_COUNT) + { + entry.layer = static_cast(layer); + } + + for (const TiXmlElement* childElement = actorElement->FirstChildElement(); childElement != NULL; childElement = childElement->NextSiblingElement()) + { + if (strcmp(childElement->Value(), "Properties") == 0) + { + ParsePropertyElement(childElement, &entry); + } + } + + m_manifest.insert(std::make_pair(alias, entry)); + } + + return true; +} + +void ActorManifest::ClearManifest() +{ + m_manifest.clear(); +} + +void ActorManifest::ParsePropertyElement(const TiXmlElement* element, ActorEntry* actorEntry) +{ + for (const TiXmlElement* propertyElement = element->FirstChildElement(); propertyElement != NULL; propertyElement = propertyElement->NextSiblingElement()) + { + if (strcmp(propertyElement->Value(), "Animation") == 0) + { + ParsePropertyElementAnimation(propertyElement, actorEntry); + actorEntry->properties |= BIT(ACTOR_PROPERTY_TYPE_ANIMATION); + } + else if (strcmp(propertyElement->Value(), "Sprite") == 0) + { + ParsePropertyElementSprite(propertyElement, actorEntry); + actorEntry->properties |= BIT(ACTOR_PROPERTY_TYPE_SPRITE); + } + else if (strcmp(propertyElement->Value(), "Physics") == 0) + { + ParsePropertyElementPhysics(propertyElement, actorEntry); + actorEntry->properties |= BIT(ACTOR_PROPERTY_TYPE_PHYSICS); + } + else if (strcmp(propertyElement->Value(), "Script") == 0) + { + ParsePropertyElementScript(propertyElement, actorEntry); + actorEntry->properties |= BIT(ACTOR_PROPERTY_TYPE_SCRIPT); + } + } +} + +void ActorManifest::ParsePropertyElementAnimation(const TiXmlElement* element, ActorEntry* actorEntry) +{ + int animationPlay = 0; + element->QueryIntAttribute("play", &animationPlay); + actorEntry->animation.play = animationPlay != 0; + + int animationLoop = 0; + element->QueryIntAttribute("loop", &animationLoop); + actorEntry->animation.loop = animationLoop != 0; + + const char* animationResource = element->Attribute("resource"); + if (animationResource != NULL) + { + actorEntry->animation.resource = animationResource; + } +} + +void ActorManifest::ParsePropertyElementSprite(const TiXmlElement* element, ActorEntry* actorEntry) +{ + const char* spriteResource = element->Attribute("resource"); + if (spriteResource != NULL) + { + actorEntry->sprite.resource = spriteResource; + } +} + +void ActorManifest::ParsePropertyElementPhysics(const TiXmlElement* element, ActorEntry* actorEntry) +{ + element->QueryFloatAttribute("velocityX", &actorEntry->physics.velocity.x); + element->QueryFloatAttribute("velocityY", &actorEntry->physics.velocity.y); +} + +void ActorManifest::ParsePropertyElementScript(const TiXmlElement* element, ActorEntry* actorEntry) +{ + const char* scriptResource = element->Attribute("resource"); + if (scriptResource != NULL) + { + actorEntry->script.resource = scriptResource; + } +} + +boost::shared_ptr ActorManifest::CreateActor(const char* actorAlias, const char* actorName, unsigned allowedProperties) const +{ + ActorMap::const_iterator iter = m_manifest.find(actorAlias); + if (iter == m_manifest.end()) + { + TRACE_ERROR(boost::format("Cannot create actor %s") % actorAlias); + return boost::shared_ptr(); + } + + const ActorEntry& actorEntry = iter->second; + boost::shared_ptr actor(new Actor(actorAlias, actorName)); + + actor->SetDynamic(actorEntry.dynamic); + actor->SetLayer(actorEntry.layer); + + if (actorEntry.properties & BIT(ACTOR_PROPERTY_TYPE_ANIMATION) & allowedProperties) + { + boost::shared_ptr property = actor->AddProperty().lock(); + + if (!actorEntry.animation.resource.empty()) + { + property->SetAnimation(actorEntry.animation.resource.c_str()); + } + + if (actorEntry.animation.play) + { + property->PlayAnimation(actorEntry.animation.loop); + } + } + + if (actorEntry.properties & BIT(ACTOR_PROPERTY_TYPE_SPRITE) & allowedProperties) + { + boost::shared_ptr property = actor->AddProperty().lock(); + property->SetSprite(actorEntry.sprite.resource.c_str()); + } + + if (actorEntry.properties & BIT(ACTOR_PROPERTY_TYPE_PHYSICS) & allowedProperties) + { + boost::shared_ptr property = actor->AddProperty().lock(); + property->SetVelocity(actorEntry.physics.velocity); + } + + if (actorEntry.properties & BIT(ACTOR_PROPERTY_TYPE_SCRIPT) & allowedProperties) + { + boost::shared_ptr property = actor->AddProperty().lock(); + property->SetScript(actorEntry.script.resource.c_str()); + } + + return actor; +} + +void ActorManifest::SummarizeActors(std::vector* summary) const +{ + for (ActorMap::const_iterator iter = m_manifest.begin(); iter != m_manifest.end(); ++iter) + { + const std::string& actorAlias = iter->first; + const ActorEntry& actorEntry = iter->second; + + boost::shared_ptr actorSurface; + if (!actorEntry.thumbnail.empty()) + { + boost::shared_ptr actorSprite = System::LoadSprite(actorEntry.thumbnail.c_str()); + if (actorSprite) + { + actorSurface = System::CreateSurface(actorSprite->GetSize(), COLOR_MODE_RGB_888); + actorSurface->Clear(Color4b(0x00, 0x00, 0xff, 0x00)); + actorSprite->Render(actorSurface); + } + } + + summary->push_back(ActorSummary(actorAlias, actorEntry.properties, actorSurface, actorEntry.layer)); + } +} + +bool ActorManifest::SummarizeActor(const char* actorAlias, ActorSummary* summary) const +{ + ActorMap::const_iterator iter = m_manifest.find(actorAlias); + if (iter == m_manifest.end()) + { + return false; + } + + const ActorEntry& actorEntry = iter->second; + + boost::shared_ptr actorSurface; + if (!actorEntry.thumbnail.empty()) + { + boost::shared_ptr actorSprite = System::LoadSprite(actorEntry.thumbnail.c_str()); + if (actorSprite) + { + actorSurface = System::CreateSurface(actorSprite->GetSize(), COLOR_MODE_RGB_888); + actorSurface->Clear(Color4b(0x00, 0x00, 0xff, 0x00)); + actorSprite->Render(actorSurface); + } + } + + *summary = ActorSummary(actorAlias, actorEntry.properties, actorSurface, actorEntry.layer); + return true; +} diff --git a/ActorManifest.h b/ActorManifest.h new file mode 100644 index 0000000..835a48c --- /dev/null +++ b/ActorManifest.h @@ -0,0 +1,74 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +class ActorManifest +{ +public: + bool LoadManifest(const char* filename); + void ClearManifest(); + + boost::shared_ptr CreateActor(const char* actorAlias, const char* actorName, unsigned allowedProperties) const; + void SummarizeActors(std::vector* summary) const; + bool SummarizeActor(const char* actorAlias, ActorSummary* summary) const; + +private: + struct ActorEntry + { + ActorEntry() : + properties(0), dynamic(false), layer(ACTOR_LAYER_GROUND1) { } + + struct + { + std::string resource; + Vector2i offset; + } sprite; + + struct + { + std::string resource; + Vector2i offset; + bool play; + bool loop; + } animation; + + struct + { + Vector2f velocity; + } physics; + + struct + { + std::string resource; + } script; + + unsigned properties; + std::string thumbnail; + bool dynamic; + ActorLayer layer; + }; + + void ParsePropertyElement(const TiXmlElement* element, ActorEntry* actorEntry); + void ParsePropertyElementAnimation(const TiXmlElement* element, ActorEntry* actorEntry); + void ParsePropertyElementSprite(const TiXmlElement* element, ActorEntry* actorEntry); + void ParsePropertyElementPhysics(const TiXmlElement* element, ActorEntry* actorEntry); + void ParsePropertyElementScript(const TiXmlElement* element, ActorEntry* actorEntry); + + typedef std::map ActorMap; + ActorMap m_manifest; +}; diff --git a/ActorProperty.cpp b/ActorProperty.cpp new file mode 100644 index 0000000..b0ba8f6 --- /dev/null +++ b/ActorProperty.cpp @@ -0,0 +1,34 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "Pch.h" +#include "ActorProperty.h" + +ActorProperty::ActorProperty(Actor* owner) : + m_owner(owner) +{ +} + +const Actor* ActorProperty::GetOwner() const +{ + return m_owner; +} + +Actor* ActorProperty::GetOwner() +{ + return m_owner; +} diff --git a/ActorProperty.h b/ActorProperty.h new file mode 100644 index 0000000..6b5a76c --- /dev/null +++ b/ActorProperty.h @@ -0,0 +1,48 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +class ActorProperty +{ +public: + ActorProperty(Actor* owner); + virtual ~ActorProperty() { } + + virtual void Render(const boost::shared_ptr& target) { } + virtual void Update(float elapsed) { } + +protected: + const Actor* GetOwner() const; + Actor* GetOwner(); + +private: + Actor* m_owner; +}; + +template +class ActorPropertyTyped : public ActorProperty +{ +public: + ActorPropertyTyped(Actor* owner) : + ActorProperty(owner) { } + + static ActorPropertyType GetStaticType( ) + { + return T; + } +}; diff --git a/ActorPropertyAnimation.cpp b/ActorPropertyAnimation.cpp new file mode 100644 index 0000000..d2bafda --- /dev/null +++ b/ActorPropertyAnimation.cpp @@ -0,0 +1,119 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "Pch.h" +#include "ActorPropertyAnimation.h" +#include "Animation.h" +#include "Surface.h" +#include "Actor.h" + +ActorPropertyAnimation::ActorPropertyAnimation(Actor* owner) : + ActorPropertyTyped(owner) +{ +} + +void ActorPropertyAnimation::Render(const boost::shared_ptr& target) +{ + if (m_animation) + { + m_animation->Render(target); + } +} + +void ActorPropertyAnimation::Update(float elapsed) +{ + bool frameChanged = false; + + if (m_animation) + { + const int frame = m_animation->GetFrame(); + m_animation->Update(elapsed); + frameChanged = frame != m_animation->GetFrame(); + } + + if (frameChanged) + { + UpdateShapes(); + } +} + +void ActorPropertyAnimation::SetAnimation(const char* resource) +{ + m_animation = System::LoadAnimation(resource); + UpdateShapes(); +} + +void ActorPropertyAnimation::PlayAnimation(bool loop) +{ + if (m_animation) + { + m_animation->Play(loop); + } +} + +bool ActorPropertyAnimation::IsAnimationPlaying() const +{ + return m_animation && m_animation->IsPlaying(); +} + +void ActorPropertyAnimation::StopAnimation() +{ + if (m_animation) + { + m_animation->Stop(); + } +} + +void ActorPropertyAnimation::RewindAnimation() +{ + if (m_animation) + { + m_animation->Rewind(); + } +} + +void ActorPropertyAnimation::PauseAnimation() +{ + if (m_animation) + { + m_animation->Pause(); + } +} + +Vector2i ActorPropertyAnimation::GetSize() const +{ + return m_animation ? m_animation->GetSize() : Vector2i(); +} + +void ActorPropertyAnimation::UpdateShapes() +{ + for (int i = 0; i < ACTOR_SHAPE_TYPE_COUNT; ++i) + { + GetOwner()->DisableShape(static_cast(i)); + } + + if (!m_animation) + { + return; + } + + const ActorShape* shapes = m_animation->GetShapes(); + for (size_t i = 0; i < ACTOR_SHAPE_TYPE_COUNT; ++i) + { + GetOwner()->SetShape(static_cast(i), shapes[i]); + } +} diff --git a/ActorPropertyAnimation.h b/ActorPropertyAnimation.h new file mode 100644 index 0000000..0dc6a04 --- /dev/null +++ b/ActorPropertyAnimation.h @@ -0,0 +1,41 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once +#include "ActorProperty.h" + +class ActorPropertyAnimation : public ActorPropertyTyped +{ +public: + ActorPropertyAnimation(Actor* owner); + + void Render(const boost::shared_ptr& target); + void Update(float elapsed); + + void SetAnimation(const char* resource); + void PlayAnimation(bool loop); + bool IsAnimationPlaying() const; + void StopAnimation(); + void RewindAnimation(); + void PauseAnimation(); + Vector2i GetSize() const; + +private: + void UpdateShapes(); + + boost::shared_ptr m_animation; +}; diff --git a/ActorPropertyPhysics.cpp b/ActorPropertyPhysics.cpp new file mode 100644 index 0000000..7cd695b --- /dev/null +++ b/ActorPropertyPhysics.cpp @@ -0,0 +1,183 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "Pch.h" +#include "ActorPropertyPhysics.h" +#include "ActorManager.h" +#include "Actor.h" + +const ActorShapeType ActorPropertyPhysics::s_collisionShapes[ACTOR_SHAPE_TYPE_COLLISION_COUNT] = +{ + ACTOR_SHAPE_TYPE_COLLISION_SOLID, + ACTOR_SHAPE_TYPE_COLLISION_INTERACT +}; + +ActorPropertyPhysics::ActorPropertyPhysics(Actor* owner) : + ActorPropertyTyped(owner) +{ +} + +void ActorPropertyPhysics::Update(float elapsed) +{ + Actor* const actor = GetOwner(); + + bool collisionShapesPresent = false; + for (int i = 0; i < ARRAY_SIZE(s_collisionShapes); ++i) + { + const ActorShapeType type = s_collisionShapes[i]; + + if (actor->IsShapeEnabled(type)) + { + Vector2i position; + Vector2i size; + int data = 0; + actor->GetShape(type, &data, &position, &size); + + collisionShapesPresent |= (data != 0); + } + + m_collisionState[type].collisions.clear(); + } + + const Vector2f newPosition = actor->GetPositionSoft() + GetVelocity() * elapsed; + + if (!collisionShapesPresent) + { + actor->SetPositionSoft(newPosition); + return; + } + + std::vector > actors; + actor->GetOwner()->EnumerateActors(&actors, actor->GetPosition()); + + actor->SetPositionSoft(newPosition); + for (int i = 0; i < ARRAY_SIZE(s_collisionShapes); ++i) + { + CollideAgainstShape(actors, s_collisionShapes[i]); + } +} + +void ActorPropertyPhysics::CollideAgainstShape(const std::vector >& actors, ActorShapeType typeAttacker) +{ + Actor* const actorAttacker = GetOwner(); + + Vector2i attackerPosition; + Vector2i attackerSize; + int attackerData = 0; + actorAttacker->GetShape(typeAttacker, &attackerData, &attackerPosition, &attackerSize); + + if (!actorAttacker->IsShapeEnabled(typeAttacker) || attackerData == 0) + { + return; + } + + for (std::vector >::const_iterator iter = actors.begin(); iter != actors.end(); ++iter) + { + const boost::shared_ptr actorDefender = iter->lock(); + + if (!actorDefender || !actorDefender->HasProperty(ACTOR_PROPERTY_TYPE_PHYSICS) || actorDefender->GetId() == actorAttacker->GetId()) + { + continue; + } + + for (int i = 0; i < ARRAY_SIZE(s_collisionShapes); ++i) + { + const ActorShapeType typeDefender = s_collisionShapes[i]; + + Vector2i defenderPosition; + Vector2i defenderSize; + int defenderData = 0; + actorDefender->GetShape(typeDefender, &defenderData, &defenderPosition, &defenderSize); + + if (!actorDefender->IsShapeEnabled(typeDefender) || (attackerData & BIT(typeDefender)) == 0) + { + continue; + } + + const Rect4i rectAttacker( + actorAttacker->GetPosition().x + attackerPosition.x, + actorAttacker->GetPosition().y + attackerPosition.y, + actorAttacker->GetPosition().x + attackerPosition.x + attackerSize.x, + actorAttacker->GetPosition().y + attackerPosition.y + attackerSize.y + ); + + const Rect4i rectDefender( + actorDefender->GetPosition().x + defenderPosition.x, + actorDefender->GetPosition().y + defenderPosition.y, + actorDefender->GetPosition().x + defenderPosition.x + defenderSize.x, + actorDefender->GetPosition().y + defenderPosition.y + defenderSize.y + ); + + if (!rectAttacker.Intersects(rectDefender)) + { + continue; + } + + if (typeAttacker != ACTOR_SHAPE_TYPE_COLLISION_SOLID || typeDefender != ACTOR_SHAPE_TYPE_COLLISION_SOLID) + { + m_collisionState[typeAttacker].collisions.push_back(actorDefender); + continue; + } + + const Rect4i intersection = rectAttacker.Intersection(rectDefender); + Vector2i displacement(0, 0); + + if (GetVelocity().x > 0) + { + displacement.x = -intersection.GetWidth(); + } + else if (GetVelocity().x < 0) + { + displacement.x = intersection.GetWidth(); + } + + if (GetVelocity().y > 0) + { + displacement.y = -intersection.GetHeight(); + } + else if (GetVelocity().y < 0) + { + displacement.y = intersection.GetHeight(); + } + + actorAttacker->SetPosition(actorAttacker->GetPosition() + displacement); + } + } +} + +void ActorPropertyPhysics::SetVelocity(const Vector2f& velocity) +{ + m_velocity = velocity; +} + +Vector2f ActorPropertyPhysics::GetVelocity() const +{ + return m_velocity; +} + +void ActorPropertyPhysics::QueryShapeCollisions(ActorShapeType type, std::vector >* actors) const +{ + ASSERT(type < ACTOR_SHAPE_TYPE_COUNT); + const CollisionState& state = m_collisionState[type]; + for (std::vector >::const_iterator iter = state.collisions.begin(); iter != state.collisions.end(); ++iter) + { + if (!iter->expired()) + { + actors->push_back(*iter); + } + } +} diff --git a/ActorPropertyPhysics.h b/ActorPropertyPhysics.h new file mode 100644 index 0000000..a3d6b3c --- /dev/null +++ b/ActorPropertyPhysics.h @@ -0,0 +1,44 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once +#include "ActorProperty.h" + +class ActorPropertyPhysics : public ActorPropertyTyped +{ +public: + ActorPropertyPhysics(Actor* owner); + + void Update(float elapsed); + + void SetVelocity(const Vector2f& velocity); + Vector2f GetVelocity() const; + void QueryShapeCollisions(ActorShapeType type, std::vector >* actors) const; + +private: + void UpdateShapes(); + void CollideAgainstShape(const std::vector >& actors, ActorShapeType typeAttacker); + + struct CollisionState + { + std::vector > collisions; + }; + + static const ActorShapeType s_collisionShapes[ACTOR_SHAPE_TYPE_COLLISION_COUNT]; + CollisionState m_collisionState[ACTOR_SHAPE_TYPE_COUNT]; + Vector2f m_velocity; +}; diff --git a/ActorPropertyScript.cpp b/ActorPropertyScript.cpp new file mode 100644 index 0000000..f268d8f --- /dev/null +++ b/ActorPropertyScript.cpp @@ -0,0 +1,100 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "Pch.h" +#include "ActorPropertyScript.h" +#include "ActorScript.h" +#include "Actor.h" + +ActorPropertyScript::ActorPropertyScript(Actor* owner) : + ActorPropertyTyped(owner), + m_queuedCreate(false) +{ +} + +ActorPropertyScript::~ActorPropertyScript() +{ + SetScript(NULL); +} + +void ActorPropertyScript::Update(float elapsed) +{ + if (m_script && System::QueryWorldContext() != NULL) + { + if (m_queuedCreate) + { + m_script->OnActorCreate(GetOwner()->GetId()); + m_queuedCreate = false; + } + + m_script->OnActorUpdate(elapsed); + } +} + +void ActorPropertyScript::SetScript(const char* resource) +{ + if (m_script) + { + m_script->OnActorDestroy(); + } + + if (resource == NULL || *resource == '\0') + { + m_script.reset(); + } + else + { + m_script = System::LoadActorScript(resource); + } + + m_queuedCreate = m_script; +} + +bool ActorPropertyScript::SendMessage(const char* message, const ParameterMap& parametersIn, ParameterMap* parametersOut) +{ + return m_script->OnActorReceiveMessage(message, parametersIn, parametersOut); +} + +void ActorPropertyScript::ResetScriptState() +{ + if (m_script) + { + m_script->ResetState(); + m_queuedCreate = true; + } +} + +void ActorPropertyScript::SetParameter(const char* name, const ScriptParameter& parameter) +{ + if (m_script) + { + m_script->SetParameter(name, parameter); + } +} + +bool ActorPropertyScript::GetParameter(const char* name, ScriptParameter* parameter) const +{ + return m_script ? m_script->GetParameter(name, parameter) : false; +} + +void ActorPropertyScript::EnumerateParameters(std::vector* names) const +{ + if (m_script) + { + m_script->EnumerateParameters(names); + } +} diff --git a/ActorPropertyScript.h b/ActorPropertyScript.h new file mode 100644 index 0000000..31985f9 --- /dev/null +++ b/ActorPropertyScript.h @@ -0,0 +1,40 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once +#include "ActorProperty.h" + +class ActorPropertyScript : public ActorPropertyTyped +{ +public: + ActorPropertyScript(Actor* owner); + ~ActorPropertyScript(); + + void Update(float elapsed); + + void SetScript(const char* resource); + bool SendMessage(const char* message, const ParameterMap& parametersIn, ParameterMap* parametersOut); + void ResetScriptState(); + + void SetParameter(const char* name, const ScriptParameter& parameter); + bool GetParameter(const char* name, ScriptParameter* parameter) const; + void EnumerateParameters(std::vector* names) const; + +private: + boost::shared_ptr m_script; + bool m_queuedCreate; +}; diff --git a/ActorPropertySprite.cpp b/ActorPropertySprite.cpp new file mode 100644 index 0000000..ab41f5b --- /dev/null +++ b/ActorPropertySprite.cpp @@ -0,0 +1,65 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "Pch.h" +#include "ActorPropertySprite.h" +#include "Sprite.h" +#include "Surface.h" +#include "Actor.h" + +ActorPropertySprite::ActorPropertySprite(Actor* owner) : + ActorPropertyTyped(owner) +{ +} + +void ActorPropertySprite::Render(const boost::shared_ptr& target) +{ + if (m_sprite) + { + m_sprite->Render(target); + } +} + +void ActorPropertySprite::SetSprite(const char* resource) +{ + m_sprite = System::LoadSprite(resource); + UpdateShapes(); +} + +Vector2i ActorPropertySprite::GetSize() const +{ + return m_sprite ? m_sprite->GetSize() : Vector2i(); +} + +void ActorPropertySprite::UpdateShapes() +{ + for (int i = 0; i < ACTOR_SHAPE_TYPE_COUNT; ++i) + { + GetOwner()->DisableShape(static_cast(i)); + } + + if (!m_sprite) + { + return; + } + + const ActorShape* shapes = m_sprite->GetShapes(); + for (size_t i = 0; i < ACTOR_SHAPE_TYPE_COUNT; ++i) + { + GetOwner()->SetShape(static_cast(i), shapes[i]); + } +} diff --git a/ActorPropertySprite.h b/ActorPropertySprite.h new file mode 100644 index 0000000..5a5c681 --- /dev/null +++ b/ActorPropertySprite.h @@ -0,0 +1,35 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once +#include "ActorProperty.h" + +class ActorPropertySprite : public ActorPropertyTyped +{ +public: + ActorPropertySprite(Actor* owner); + + void Render(const boost::shared_ptr& target); + + void SetSprite(const char* resource); + Vector2i GetSize() const; + +private: + void UpdateShapes(); + + boost::shared_ptr m_sprite; +}; diff --git a/ActorScript.cpp b/ActorScript.cpp new file mode 100644 index 0000000..3f3eb00 --- /dev/null +++ b/ActorScript.cpp @@ -0,0 +1,81 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "Pch.h" +#include "ActorScript.h" + +ActorScript::ActorScript(const boost::shared_ptr& script) : + Script(script) +{ +} + +void ActorScript::OnActorCreate(Token id) +{ + GetBinding()->GetGlobal("OnActorCreate"); + if (!GetBinding()->IsFunction(GetBinding()->GetTop())) + { + GetBinding()->Pop(1); + return; + } + + GetBinding()->Push(id); + GetBinding()->Push(GetParameters()); + GetBinding()->Call(2, 0); +} + +void ActorScript::OnActorDestroy() +{ + GetBinding()->GetGlobal("OnActorDestroy"); + if (!GetBinding()->IsFunction(GetBinding()->GetTop())) + { + GetBinding()->Pop(1); + return; + } + + GetBinding()->Call(0, 0); +} + +void ActorScript::OnActorUpdate(float elapsed) +{ + GetBinding()->GetGlobal("OnActorUpdate"); + if (!GetBinding()->IsFunction(GetBinding()->GetTop())) + { + GetBinding()->Pop(1); + return; + } + + GetBinding()->Push(elapsed); + GetBinding()->Call(1, 0); +} + +bool ActorScript::OnActorReceiveMessage(const char* message, const ParameterMap& parametersIn, ParameterMap* parametersOut) +{ + GetBinding()->GetGlobal("OnActorReceiveMessage"); + if (!GetBinding()->IsFunction(GetBinding()->GetTop())) + { + GetBinding()->Pop(1); + return false; + } + + GetBinding()->Push(message); + GetBinding()->Push(parametersIn); + GetBinding()->Call(2, 1); + + const bool responded = GetBinding()->Peek(GetBinding()->GetTop(), parametersOut); + GetBinding()->Pop(1); + return responded; +} diff --git a/ActorScript.h b/ActorScript.h new file mode 100644 index 0000000..ecd4156 --- /dev/null +++ b/ActorScript.h @@ -0,0 +1,30 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once +#include "Script.h" + +class ActorScript : public Script +{ +public: + ActorScript(const boost::shared_ptr& script); + + void OnActorCreate(Token id); + void OnActorDestroy(); + void OnActorUpdate(float elapsed); + bool OnActorReceiveMessage(const char* message, const ParameterMap& parametersIn, ParameterMap* parametersOut); +}; diff --git a/Animation.cpp b/Animation.cpp new file mode 100644 index 0000000..d3c555e --- /dev/null +++ b/Animation.cpp @@ -0,0 +1,110 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "Pch.h" +#include "Animation.h" +#include "Sprite.h" + +Animation::Animation(const std::vector& frames) : + m_frames(frames), + m_elapsed(0), + m_index(0), + m_loop(false), + m_play(false) +{ + ASSERT(frames.size() > 0); +} + +void Animation::Update(float elapsed) +{ + if (!m_play) + { + return; + } + + m_elapsed += elapsed; + + while (m_elapsed > m_frames[m_index].delay) + { + m_elapsed -= m_frames[m_index++].delay; + + if (m_index == static_cast(m_frames.size())) + { + if (m_loop) + { + m_index = 0; + } + else + { + m_play = false; + --m_index; + } + } + } +} + +void Animation::Render(const boost::shared_ptr& target) +{ + m_frames[m_index].sprite->Render(target); +} + +Vector2i Animation::GetSize() const +{ + return m_frames[m_index].sprite->GetSize(); +} + +const ActorShape* Animation::GetShapes() const +{ + return m_frames[m_index].sprite->GetShapes(); +} + +int Animation::GetFrameCount() const +{ + return static_cast(m_frames.size()); +} + +int Animation::GetFrame() const +{ + return m_index; +} + +void Animation::Play(bool loop) +{ + m_loop = loop; + m_play = true; +} + +void Animation::Stop() +{ + Rewind(); + Pause(); +} + +void Animation::Rewind() +{ + m_index = 0; +} + +void Animation::Pause() +{ + m_play = false; +} + +bool Animation::IsPlaying() const +{ + return m_play; +} diff --git a/Animation.h b/Animation.h new file mode 100644 index 0000000..66f25a2 --- /dev/null +++ b/Animation.h @@ -0,0 +1,55 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once +#include "Actor.h" + +class Animation : private boost::noncopyable +{ +public: + struct Frame + { + Frame(const boost::shared_ptr& sprite, float delay) : + sprite(sprite), delay(delay) { } + + boost::shared_ptr sprite; + float delay; + }; + + Animation(const std::vector& frames); + + void Update(float elapsed); + void Render(const boost::shared_ptr& target); + + Vector2i GetSize() const; + const ActorShape* GetShapes() const; + int GetFrameCount() const; + int GetFrame() const; + + void Play(bool loop); + void Stop(); + void Rewind(); + void Pause(); + bool IsPlaying() const; + +private: + std::vector m_frames; + float m_elapsed; + int m_index; + bool m_loop; + bool m_play; +}; diff --git a/AnimationManifest.cpp b/AnimationManifest.cpp new file mode 100644 index 0000000..73dfc10 --- /dev/null +++ b/AnimationManifest.cpp @@ -0,0 +1,121 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "Pch.h" +#include "AnimationManifest.h" +#include "Animation.h" + +bool AnimationManifest::LoadManifest(const char* filename) +{ + boost::shared_ptr buffer = System::LoadFile(filename); + if (!buffer) + { + TRACE_ERROR(boost::format("Cannot load animation manifest %s") % filename); + return false; + } + + TiXmlDocument document; + if (!document.Parse(static_cast(buffer->Get()))) + { + TRACE_ERROR(boost::format("Cannot parse animation manifest %s") % filename); + return false; + } + + const TiXmlElement* rootElement = document.RootElement(); + if (rootElement == NULL || strcmp(rootElement->Value(), "Manifest") != 0) + { + return false; + } + + for (const TiXmlElement* animationElement = rootElement->FirstChildElement(); animationElement != NULL; animationElement = animationElement->NextSiblingElement()) + { + if (strcmp(animationElement->Value(), "Animation") != 0) + { + continue; + } + + const char* alias = animationElement->Attribute("alias"); + if (alias == NULL) + { + TRACE_WARNING("Animation definition is missing required fields"); + continue; + } + + if (m_manifest.find(alias) != m_manifest.end()) + { + TRACE_WARNING(boost::format("Duplicate animation %s") % alias); + continue; + } + + float defaultDelay = 1; + animationElement->QueryFloatAttribute("delay", &defaultDelay); + + AnimationEntry entry; + for (const TiXmlElement* spriteElement = animationElement->FirstChildElement(); spriteElement != NULL; spriteElement = spriteElement->NextSiblingElement()) + { + if (strcmp(spriteElement->Value(), "Frame") != 0) + { + continue; + } + + const char* sprite = spriteElement->Attribute("sprite"); + if (sprite == NULL) + { + TRACE_WARNING("Animation frame definition is missing required fields"); + continue; + } + + float delay = defaultDelay; + spriteElement->QueryFloatAttribute("delay", &delay); + + entry.frames.push_back(AnimationFrame(sprite, delay)); + } + + m_manifest.insert(std::make_pair(alias, entry)); + } + + return true; +} + +void AnimationManifest::ClearManifest() +{ + m_manifest.clear(); +} + +boost::shared_ptr AnimationManifest::LoadAnimation(const char* animationAlias) const +{ + AnimationMap::const_iterator iter = m_manifest.find(animationAlias); + if (iter == m_manifest.end()) + { + TRACE_ERROR(boost::format("Cannot load animation %s") % animationAlias); + return boost::shared_ptr(); + } + + std::vector frames; + for (size_t i = 0; i < iter->second.frames.size(); ++i) + { + boost::shared_ptr sprite = System::LoadSprite(iter->second.frames[i].alias.c_str()); + if (!sprite) + { + return boost::shared_ptr(); + } + + frames.push_back(Animation::Frame(sprite, iter->second.frames[i].delay)); + } + + return boost::shared_ptr(new Animation(frames)); +} diff --git a/AnimationManifest.h b/AnimationManifest.h new file mode 100644 index 0000000..5cc7353 --- /dev/null +++ b/AnimationManifest.h @@ -0,0 +1,45 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +class AnimationManifest +{ +public: + bool LoadManifest(const char* filename); + void ClearManifest(); + + boost::shared_ptr LoadAnimation(const char* animationAlias) const; + +private: + struct AnimationFrame + { + AnimationFrame(const std::string& alias, float delay) : + alias(alias), delay(delay) { } + + std::string alias; + float delay; + }; + + struct AnimationEntry + { + std::vector frames; + }; + + typedef std::map AnimationMap; + AnimationMap m_manifest; +}; diff --git a/AppMoonfall.cpp b/AppMoonfall.cpp new file mode 100644 index 0000000..f813f7b --- /dev/null +++ b/AppMoonfall.cpp @@ -0,0 +1,139 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "Pch.h" +#include "AppMoonfall.h" +#include "FrameConsole.h" +#include "WindowMain.h" + +AppMoonfall::AppMoonfall() : + m_dialogAssetPackager(NULL), + m_frameSpriteEditor(NULL), + m_frameMapEditor(NULL), + m_frameConsole(NULL), + m_done(false) +{ +} + +AppMoonfall::~AppMoonfall() +{ +#ifdef HEAP_TRACK + if (Heap::HasAllocs()) + { + TRACE_WARNING("Memory leaks detected"); + + std::vector blocks; + Heap::DumpAllocs(&blocks); + + for (std::vector::iterator iter = blocks.begin(); iter != blocks.end(); ++iter) + { + TRACE_WARNING( + boost::format("Block:\n\tAddress = %p\n\tSize = %d\n\tFilename = %s\n\tLine = %d") % iter->address % iter->size % iter->filename % iter->line + ); + } + } + + ASSERT(!Heap::HasAllocs()); + Heap::TrackEnd(); +#endif + + System::RemoveEventHandler(this); + Trace::RemoveTarget(this); +} + +bool AppMoonfall::OnInit() +{ +#ifdef HEAP_TRACK + Heap::TrackBegin(); +#endif + wxInitAllImageHandlers(); + wxXmlResource::Get()->InitAllHandlers(); + void InitXmlResource(); + InitXmlResource(); + + m_frameConsole = new FrameConsole(NULL, this); + m_done = false; + + Trace::AddTarget(this); + System::AddEventHandler(this); + + const Vector2i size(800, 600); + +#ifdef DEVELOPER + const char title[] = "Moonfall - Developer"; +#else + const char title[] = "Moonfall"; +#endif + +#ifdef WINDOWS + wxFrame* frameSdl = new wxFrame( + NULL, + wxID_ANY, + wxEmptyString, + wxDefaultPosition, + wxDefaultSize, + wxSYSTEM_MENU | wxMINIMIZE_BOX | wxCLOSE_BOX | wxCAPTION + ); + frameSdl->SetClientSize(size.x, size.y); + frameSdl->Show(); + static char s_id[32] = {0}; + sprintf(s_id, "%u", frameSdl->GetHandle()); + SetEnvironmentVariableA("SDL_WINDOWID", s_id); +#endif + + if (!m_driver.Initialize(title)) + { + return false; + } + + System::CreateFramebufferSurface(size, COLOR_MODE_RGB_888); + System::EnqueueWindow(boost::shared_ptr(new WindowMain())); + return true; +} + +int AppMoonfall::OnExit() +{ + m_driver.Shutdown(); + + // all windows are destroyed by the time execution enters + // the destructor, so clear these would-be dangling pointers + m_dialogAssetPackager = NULL; + m_frameConsole = NULL; + m_frameMapEditor = NULL; + + return 0; +} + +bool AppMoonfall::ProcessIdle() +{ + wxApp::ProcessIdle(); + m_driver.Update(); + + if (m_done) + { + ExitMainLoop(); + } + + return !m_done; +} + +void AppMoonfall::OnQuit() +{ + m_done = true; +} + +IMPLEMENT_APP(AppMoonfall) diff --git a/AppMoonfall.h b/AppMoonfall.h new file mode 100644 index 0000000..d31c191 --- /dev/null +++ b/AppMoonfall.h @@ -0,0 +1,62 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once +#include "Driver.h" +#include "LuaBinding.h" +#include "FrameConsole.h" +#include "IEventHandler.h" + +class FrameMapEditor; +class FrameSpriteEditor; +class DialogAssetPackager; + +class AppMoonfall : public wxApp, public IEventHandler, public FrameConsole::IListener, public Trace::ITarget +{ +public: + AppMoonfall(); + ~AppMoonfall(); + +private: + bool OnInit(); + bool ProcessIdle(); + int OnExit(); + + void Trace(Trace::Level level, const char* text, const char* context); + + void OnKeyDown(const InputKey& args); + void OnKeyUp(const InputKey& args) { } + void OnMouseMove(const InputMouse& args) { } + void OnMouseButtonDown(const InputMouse& args) { } + void OnMouseButtonUp(const InputMouse& args) { } + void OnMouseWheel(const InputMouse& args) { } + void OnActivate() { } + void OnDeactivate() { } + void OnQuit(); + + void OnConsoleInput(FrameConsole* console, const wxString& text); + bool OnConsoleClose(FrameConsole* console); + + DialogAssetPackager* m_dialogAssetPackager; + FrameSpriteEditor* m_frameSpriteEditor; + FrameMapEditor* m_frameMapEditor; + FrameConsole* m_frameConsole; + + LuaBinding m_binding; + Driver m_driver; + bool m_done; +}; diff --git a/AppMoonfallDev.cpp b/AppMoonfallDev.cpp new file mode 100644 index 0000000..a829a72 --- /dev/null +++ b/AppMoonfallDev.cpp @@ -0,0 +1,216 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "Pch.h" +#include "AppMoonfall.h" +#include "DialogAssetPackager.h" +#include "FrameConsole.h" +#include "FrameMapEditor.h" +#include "FrameSpriteEditor.h" + +void AppMoonfall::OnKeyDown(const InputKey& args) +{ + if (args.key == '`') + { + m_frameConsole->Show(); + m_frameConsole->Raise(); + } +} + +void AppMoonfall::OnConsoleInput(FrameConsole* console, const wxString& text) +{ + const wxColor echoColor(0x80, 0x80, 0x80); + const wxString command = text.BeforeFirst(' '); + + console->Write(wxT("> ") + text + wxT("\n"), echoColor); + + if (command == wxT("/clear")) + { + console->Clear(); + } + else if (command == wxT("/quit")) + { + ExitMainLoop(); + } + else if (command == wxT("/help")) + { + console->Write( + wxT("/help\n") +#ifdef DEVELOPER + wxT("/edit [sprites | assets | maps]\n") + wxT("/show [layer | shapes | backdrop]\n") + wxT("/hide [layer | shapes | backdrop]\n") + wxT("/lua [code]\n") + wxT("/flush\n") + wxT("/vis\n") +#endif + wxT("/clear\n") + wxT("/quit\n"), + echoColor + ); + } +#ifdef DEVELOPER + else if (command == wxT("/flush")) + { + System::FlushFiles(); + System::FlushSurfaces(); + } + else if (command == wxT("/lua")) + { + const wxString parameter = text.AfterFirst(' '); + m_binding.DoString(parameter.ToAscii()); + } + else if (command == wxT("/edit")) + { + const wxString type = text.AfterFirst(' '); + if (type == wxT("sprites")) + { + if (m_frameSpriteEditor == NULL) + { + m_frameSpriteEditor = new FrameSpriteEditor(NULL, wxT("Assets/SpriteManifest.xml")); + } + m_frameSpriteEditor->Show(); + m_frameSpriteEditor->Raise(); + } + else if (type == wxT("assets")) + { + if (m_dialogAssetPackager == NULL) + { + m_dialogAssetPackager = new DialogAssetPackager(NULL, wxT("Assets"), wxT("Assets.pak")); + } + m_dialogAssetPackager->Show(); + m_dialogAssetPackager->Raise(); + } + else if (type == wxT("maps")) + { + if (m_frameMapEditor == NULL) + { + m_frameMapEditor = new FrameMapEditor(NULL); + } + m_frameMapEditor->Show(); + m_frameMapEditor->Raise(); + } + } + else if (command == wxT("/vis")) + { + IWorldContext * const context = System::QueryWorldContext(); + if (context == NULL) + { + return; + } + + const wchar_t* visibility[] = { L"hidden", L"visible" }; + + console->Write(wxString::Format(wxT("Backdrop: %s\n"), visibility[context->IsBackdropSpriteVisible()]), echoColor); + for (int i = 0; i < ACTOR_LAYER_COUNT; ++i) + { + console->Write(wxString::Format(wxT("Layer %d: %s\n"), i, visibility[context->IsLayerVisible(static_cast(i))]), echoColor); + } + console->Write(wxString::Format(wxT("Shapes: %s\n"), visibility[context->AreShapesVisible()]), echoColor); + } + else if (command == wxT("/show") || command == wxT("/hide")) + { + IWorldContext * const context = System::QueryWorldContext(); + if (context == NULL) + { + return; + } + + const wxString remainder = text.AfterFirst(' '); + const wxString type = remainder.BeforeFirst(' '); + const bool show = command == wxT("/show"); + + if (type == wxT("layer")) + { + long layer = 0; + if (!remainder.AfterFirst(' ').ToLong(&layer)) + { + return; + } + + if (show) + { + context->ShowLayer(static_cast(layer)); + } + else + { + context->HideLayer(static_cast(layer)); + } + } + else if (type == wxT("shapes")) + { + if (show) + { + context->ShowShapes(); + } + else + { + context->HideShapes(); + } + } + else if (type == wxT("backdrop")) + { + if (show) + { + context->ShowBackdropSprite(); + } + else + { + context->HideBackdropSprite(); + } + } + } +#endif + else + { + console->Write(wxT("Unrecognized command ") + command + wxT("\n"), echoColor); + } +} + +bool AppMoonfall::OnConsoleClose(FrameConsole* console) +{ + return false; +} + +void AppMoonfall::Trace(Trace::Level level, const char* text, const char* context) +{ + static const wxColor s_colorLocation(0xff, 0xff, 0xff); + static const wxColor s_colors[] = + { + wxColor(0x00, 0xff, 0x00), + wxColor(0xff, 0xff, 0x00), + wxColor(0xff, 0x00, 0x00) + }; + + ASSERT(level < ARRAY_SIZE(s_colors)); + + if (m_frameConsole != NULL) + { + if (context != NULL) + { + m_frameConsole->Write(wxString::FromAscii(context) + wxT(" - "), s_colorLocation); + } + m_frameConsole->Write(wxString::FromAscii(text) + wxT("\n"), s_colors[level]); + } + +#ifdef DEVELOPER + if (m_frameConsole != NULL && level >= Trace::LEVEL_WARNING) + { + m_frameConsole->Show(); + } +#endif +} diff --git a/Assert.cpp b/Assert.cpp new file mode 100644 index 0000000..5e9a42e --- /dev/null +++ b/Assert.cpp @@ -0,0 +1,31 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "Pch.h" +#include "Assert.h" + +void AssertFail(const char* expression, const char* filename, int line) +{ + const char* body = strrchr(filename, PATH_SEPARATOR); + if (body != NULL) + { + filename = body + 1; + } + + TRACE_ERROR(boost::format("Assertion \"%s\" failed in %s:%d") % expression % filename % line); + abort(); +} diff --git a/Assert.h b/Assert.h new file mode 100644 index 0000000..4c4aab8 --- /dev/null +++ b/Assert.h @@ -0,0 +1,24 @@ +/* + Moonfall Copyright (C) 2008 Alex Yatskov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +void AssertFail(const char* expression, const char* filename, int line); + +#define ASSERT(exp) ((exp) ? static_cast(NULL) : AssertFail(#exp, __FILE__, __LINE__)) +#undef assert +#define assert(exp) ASSERT(exp) diff --git a/Assets.pak b/Assets.pak new file mode 100644 index 0000000..f16f6f5 Binary files /dev/null and b/Assets.pak differ diff --git a/Assets/.svn/all-wcprops b/Assets/.svn/all-wcprops new file mode 100644 index 0000000..a838c1e --- /dev/null +++ b/Assets/.svn/all-wcprops @@ -0,0 +1,47 @@ +K 25 +svn:wc:ra_dav:version-url +V 29 +/moonfall/!svn/ver/581/Assets +END +DialogueManifest.xml +K 25 +svn:wc:ra_dav:version-url +V 50 +/moonfall/!svn/ver/536/Assets/DialogueManifest.xml +END +AnimationManifest.xml +K 25 +svn:wc:ra_dav:version-url +V 51 +/moonfall/!svn/ver/524/Assets/AnimationManifest.xml +END +ScriptManifest.xml +K 25 +svn:wc:ra_dav:version-url +V 48 +/moonfall/!svn/ver/473/Assets/ScriptManifest.xml +END +FontManifest.xml +K 25 +svn:wc:ra_dav:version-url +V 46 +/moonfall/!svn/ver/509/Assets/FontManifest.xml +END +SpriteManifest.xml +K 25 +svn:wc:ra_dav:version-url +V 48 +/moonfall/!svn/ver/528/Assets/SpriteManifest.xml +END +WorldManifest.xml +K 25 +svn:wc:ra_dav:version-url +V 47 +/moonfall/!svn/ver/419/Assets/WorldManifest.xml +END +ActorManifest.xml +K 25 +svn:wc:ra_dav:version-url +V 47 +/moonfall/!svn/ver/524/Assets/ActorManifest.xml +END diff --git a/Assets/.svn/entries b/Assets/.svn/entries new file mode 100644 index 0000000..e48e895 --- /dev/null +++ b/Assets/.svn/entries @@ -0,0 +1,281 @@ +10 + +dir +603 +http://svn.foosoft.net/moonfall/Assets +http://svn.foosoft.net/moonfall + + + +2009-03-29T18:37:58.976404Z +581 +foosoft + + + + + + + + + + + + + + +db075b95-f451-0410-a043-dbb6c79280e7 + +DialogueManifest.xml +file + + + + +2009-11-14T21:48:14.834133Z +3a82f4ce3a051133b12f02ec6990457c +2009-01-02T22:30:18.498082Z +536 +foosoft + + + + + + + + + + + + + + + + + + + + + +96 + +Graphics +dir + +AnimationManifest.xml +file + + + + +2009-11-14T21:48:14.834133Z +51d0caec0c9d20263804ec1f3974358c +2009-01-01T08:46:23.332956Z +524 +foosoft + + + + + + + + + + + + + + + + + + + + + +25054 + +Scripts +dir + +Dialogue +dir + +Fonts +dir + +Worlds +dir + +ScriptManifest.xml +file + + + + +2009-11-14T21:48:14.834133Z +c2bbe4a684bf1c4eb72cdc4332e1f346 +2008-12-11T02:23:26.246113Z +473 +pash + + + + + + + + + + + + + + + + + + + + + +2951 + +FontManifest.xml +file + + + + +2009-11-14T21:48:14.834133Z +2e1037ff0e1d56d02d73957d37494a7e +2008-12-29T05:20:56.238772Z +509 +foosoft + + + + + + + + + + + + + + + + + + + + + +265 + +SpriteManifest.xml +file + + + + +2009-11-14T21:48:14.834133Z +b0a592937e44ded19930ae1600cd5f7a +2009-01-02T06:56:03.326001Z +528 +foosoft + + + + + + + + + + + + + + + + + + + + + +91894 + +WorldManifest.xml +file + + + + +2009-11-14T21:48:14.834133Z +f4d64c28e94b81a78efd9154aa0db98d +2008-11-29T22:06:17.998709Z +419 +foosoft + + + + + + + + + + + + + + + + + + + + + +187 + +ActorManifest.xml +file + + + + +2009-11-14T21:48:14.834133Z +6610b98eb65be9b832575697c9e7ceb9 +2009-01-01T08:46:23.332956Z +524 +foosoft + + + + + + + + + + + + + + + + + + + + + +44880 + diff --git a/Assets/.svn/text-base/ActorManifest.xml.svn-base b/Assets/.svn/text-base/ActorManifest.xml.svn-base new file mode 100644 index 0000000..0d38a85 --- /dev/null +++ b/Assets/.svn/text-base/ActorManifest.xml.svn-base @@ -0,0 +1,1155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +