| @@ -757,24 +757,18 @@ Global | |||
| {81C83B42-D00A-4FA3-9A3D-80F9D46524BF}.Release|x64.ActiveCfg = Release|x64 | |||
| {81C83B42-D00A-4FA3-9A3D-80F9D46524BF}.Release|x64.Build.0 = Release|x64 | |||
| {81C83B42-D00A-4FA3-9A3D-80F9D46524BF}.Release|Xbox 360.ActiveCfg = Release|Win32 | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Debug|ORBIS.ActiveCfg = Debug|ORBIS | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Debug|ORBIS.Build.0 = Debug|ORBIS | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Debug|ORBIS.ActiveCfg = Debug|Win32 | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Debug|Win32.ActiveCfg = Debug|Win32 | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Debug|Win32.Build.0 = Debug|Win32 | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Debug|x64.ActiveCfg = Debug|x64 | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Debug|x64.Build.0 = Debug|x64 | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Debug|Xbox 360.ActiveCfg = Debug|Xbox 360 | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Debug|Xbox 360.Build.0 = Debug|Xbox 360 | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Debug|Xbox 360.Deploy.0 = Debug|Xbox 360 | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Release|ORBIS.ActiveCfg = Release|ORBIS | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Release|ORBIS.Build.0 = Release|ORBIS | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Debug|Xbox 360.ActiveCfg = Debug|Win32 | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Release|ORBIS.ActiveCfg = Release|Win32 | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Release|Win32.ActiveCfg = Release|Win32 | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Release|Win32.Build.0 = Release|Win32 | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Release|x64.ActiveCfg = Release|x64 | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Release|x64.Build.0 = Release|x64 | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Release|Xbox 360.ActiveCfg = Release|Xbox 360 | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Release|Xbox 360.Build.0 = Release|Xbox 360 | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Release|Xbox 360.Deploy.0 = Release|Xbox 360 | |||
| {B9A255A0-2B92-4801-AF6C-354535A6E105}.Release|Xbox 360.ActiveCfg = Release|Win32 | |||
| EndGlobalSection | |||
| GlobalSection(SolutionProperties) = preSolution | |||
| HideSolutionNode = FALSE | |||
| @@ -41,6 +41,7 @@ struct InitState | |||
| class Entity | |||
| { | |||
| friend class Scene; | |||
| friend class Ticker; | |||
| friend class TickerData; | |||
| friend class Dict; | |||
| @@ -146,6 +147,7 @@ private: | |||
| private: | |||
| int m_ref, m_autorelease, m_destroy; | |||
| uint64_t m_scene_mask = 0; | |||
| }; | |||
| } /* namespace lol */ | |||
| @@ -253,7 +253,7 @@ void NaClInputData::Tick(float seconds) | |||
| //---- | |||
| void NaClInputData::InitViewportSize() | |||
| { | |||
| if (g_scene) | |||
| if (g_scenes.count()) | |||
| { | |||
| m_app = vec2(Video::GetSize()); | |||
| //Dunno if its the good idea. | |||
| @@ -27,10 +27,10 @@ namespace lol | |||
| { | |||
| /* | |||
| * The global g_scene object, initialised by Video::Init | |||
| * The global g_scenes object, initialised by Video::Init | |||
| */ | |||
| Scene *Scene::g_scene = nullptr; | |||
| array<Scene*> Scene::g_scenes; | |||
| /* | |||
| * A quick and dirty Tile structure for 2D blits | |||
| @@ -55,8 +55,25 @@ class SceneData | |||
| friend class Scene; | |||
| private: | |||
| SceneData() | |||
| { | |||
| /* TODO: FIX THAT */ | |||
| ASSERT(!(m_used_id & ((uint64_t)1 << 63)), "Too many scenes !!!!"); | |||
| m_mask_id = m_used_id; | |||
| m_used_id = m_used_id << 1; | |||
| } | |||
| /* Mask ID */ | |||
| /* TODO: Do a mask class that handles more than 64 slots */ | |||
| static uint64_t m_used_id; | |||
| uint64_t m_mask_id = 0; | |||
| /* New scenegraph */ | |||
| array<Primitive*> m_primitives; | |||
| /* Primitives will be kept until: | |||
| * - Updated by entity | |||
| * - Scene is destroyed */ | |||
| map<uint32_t, array<Primitive*, PrimitiveSettings*> > m_primitives_; | |||
| /* Old API <P0, P1, COLOR, TIME, MASK> */ | |||
| float m_new_line_time; | |||
| @@ -81,6 +98,7 @@ private: | |||
| Camera *m_default_cam; | |||
| array<Camera *> m_camera_stack; | |||
| }; | |||
| uint64_t SceneData::m_used_id = 1; | |||
| /* | |||
| * Public Scene class | |||
| @@ -127,24 +145,64 @@ Scene::~Scene() | |||
| delete data; | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| Scene* Scene::AddNew(ivec2 size) | |||
| { | |||
| Scene::g_scenes << new Scene(size); | |||
| return Scene::g_scenes.last(); | |||
| } | |||
| void Scene::DestroyScene(Scene* scene) | |||
| { | |||
| Scene::g_scenes.remove_item(scene); | |||
| delete scene; | |||
| } | |||
| void Scene::DestroyAll() | |||
| { | |||
| while (Scene::g_scenes.count()) | |||
| delete Scene::g_scenes.pop(); | |||
| } | |||
| ptrdiff_t Scene::GetCount() | |||
| { | |||
| return g_scenes.count(); | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| Scene* Scene::GetScene(ptrdiff_t index) | |||
| { | |||
| ASSERT(0 <= index && index < g_scenes.count(), "Trying to get a non-existent scene"); | |||
| return g_scenes[index]; | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| bool Scene::GetScene(Scene*& scene) | |||
| { | |||
| ASSERT(!!g_scene, "Trying to access a non-ready scene"); | |||
| return (scene = g_scene) != nullptr; | |||
| ASSERT(!!g_scenes.count(), "Trying to access a non-ready scene"); | |||
| return (scene = g_scenes[0]) != nullptr; | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| bool Scene::GetSceneData(SceneData*& data) | |||
| { | |||
| ASSERT(!!g_scene, "Trying to access a non-ready scene"); | |||
| return (data = g_scene->data) != nullptr; | |||
| ASSERT(!!g_scenes.count(), "Trying to access a non-ready scene"); | |||
| return (data = g_scenes[0]->data) != nullptr; | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| bool Scene::IsReady() | |||
| { | |||
| return !!g_scene; | |||
| return !!g_scenes[0]; | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| void Scene::Apply(Entity* entity) | |||
| { | |||
| entity->m_scene_mask |= data->m_mask_id; | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| bool Scene::IsRelevant(Entity* entity) | |||
| { | |||
| return !!(entity->m_scene_mask & data->m_mask_id); | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| @@ -250,6 +308,12 @@ void Scene::AddPrimitive(Primitive* primitive) | |||
| data->m_primitives.Push(primitive); | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| void Scene::AddPrimitive(Entity* entity, Primitive* primitive) | |||
| { | |||
| data->m_primitives_[(uint32_t)entity /* I don't like that */].push(primitive, nullptr); | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| void Scene::AddTile(TileSet *tileset, int id, vec3 pos, int o, vec2 scale, float angle) | |||
| { | |||
| @@ -42,25 +42,49 @@ public: | |||
| private: | |||
| }; | |||
| class PrimitiveSettings | |||
| { | |||
| friend class Scene; | |||
| public: | |||
| PrimitiveSettings() { } | |||
| virtual ~PrimitiveSettings() { } | |||
| virtual void ApplyTo(Primitive* primitive) const { } | |||
| private: | |||
| }; | |||
| //----------------------------------------------------------------------------- | |||
| //----------------------------------------------------------------------------- | |||
| class Scene | |||
| { | |||
| friend class Video; | |||
| friend class TickerData; //TODO: Smells shitty | |||
| private: | |||
| static Scene *g_scene; | |||
| static array<Scene*> g_scenes; | |||
| Scene(ivec2 size); | |||
| ~Scene(); | |||
| public: | |||
| static Scene* AddNew(ivec2 size); | |||
| static void DestroyScene(Scene* scene); | |||
| static void DestroyAll(); | |||
| static ptrdiff_t GetCount(); | |||
| static Scene* GetScene(ptrdiff_t index); | |||
| private: | |||
| static bool GetScene(Scene*& scene); | |||
| static bool GetSceneData(SceneData*& data); | |||
| public: | |||
| static bool IsReady(); | |||
| //TODO: don't like the name | |||
| void Apply(Entity* entity); | |||
| bool IsRelevant(Entity* entity); | |||
| static Camera *GetCamera(int cam_idx=-1); | |||
| public: | |||
| static Camera *GetCamera(int cam_idx = -1); | |||
| private: | |||
| static int PushCamera(Scene* scene, Camera *cam); | |||
| static void PopCamera(Scene* scene, Camera *cam); | |||
| @@ -74,6 +98,7 @@ public: | |||
| /* New scenegraph */ | |||
| void AddPrimitive(Mesh const &mesh, mat4 const &matrix); | |||
| void AddPrimitive(Primitive* primitive); | |||
| void AddPrimitive(Entity* entity, Primitive* primitive); | |||
| /* FIXME: this should be deprecated -- it doesn't really match | |||
| * the architecture we want to build */ | |||
| @@ -57,7 +57,8 @@ public: | |||
| private: | |||
| /* Entity management */ | |||
| array<Entity *> m_todolist, m_autolist; | |||
| array<Entity *> m_list[Entity::ALLGROUP_END]; //TODO: Add NO-DRAW entity support | |||
| array<Entity *> m_list[Entity::ALLGROUP_END]; | |||
| array<ptrdiff_t> m_scenes[Entity::ALLGROUP_END]; | |||
| ptrdiff_t nentities; | |||
| /* Fixed framerate management */ | |||
| @@ -328,10 +329,32 @@ void TickerData::GameThreadTick() | |||
| { | |||
| Entity *e = data->m_todolist.Last(); | |||
| data->m_todolist.Remove(-1); | |||
| data->m_list[e->m_gamegroup].Push(e); | |||
| //If the entity has no mask, default it | |||
| if (e->m_scene_mask == 0) | |||
| { | |||
| Scene::GetScene(0)->Apply(e); | |||
| } | |||
| data->m_todolist.remove(-1); | |||
| data->m_list[e->m_gamegroup].push(e); | |||
| if (e->m_drawgroup != Entity::DRAWGROUP_NONE) | |||
| data->m_list[e->m_drawgroup].Push(e); | |||
| { | |||
| if (data->m_scenes[e->m_drawgroup].count() < Scene::GetCount()) | |||
| data->m_scenes[e->m_drawgroup].resize(Scene::GetCount()); | |||
| ptrdiff_t add = 0; | |||
| for (ptrdiff_t i = 0; i < Scene::GetCount(); i++) | |||
| { | |||
| //If entity is concerned by this scene, add it in the list | |||
| if (Scene::GetScene(i)->IsRelevant(e)) | |||
| { | |||
| data->m_list[e->m_drawgroup].insert(e, data->m_scenes[e->m_drawgroup][i]); | |||
| add++; | |||
| } | |||
| //Update scene index | |||
| data->m_scenes[e->m_drawgroup][i] += add; | |||
| } | |||
| } | |||
| // Initialize the entity | |||
| e->InitGame(); | |||
| @@ -340,10 +363,9 @@ void TickerData::GameThreadTick() | |||
| /* Tick objects for the game loop */ | |||
| for (int g = Entity::GAMEGROUP_BEGIN; g < Entity::GAMEGROUP_END && !data->quit /* Stop as soon as required */; ++g) | |||
| { | |||
| for (int i = 0; i < data->m_list[g].Count() && !data->quit /* Stop as soon as required */; ++i) | |||
| for (ptrdiff_t i = 0; i < data->m_list[g].Count() && !data->quit /* Stop as soon as required */; ++i) | |||
| { | |||
| Entity *e = data->m_list[g][i]; | |||
| if (!e->m_destroy) | |||
| { | |||
| #if !LOL_BUILD_RELEASE | |||
| @@ -374,6 +396,8 @@ void TickerData::DrawThreadTick() | |||
| /* Tick objects for the draw loop */ | |||
| for (int g = Entity::DRAWGROUP_BEGIN; g < Entity::DRAWGROUP_END && !data->quit /* Stop as soon as required */; ++g) | |||
| { | |||
| ptrdiff_t scene_idx = 0; | |||
| //Scene::GetScene[scene_idx]->EnableDisplay(); //TODO | |||
| switch (g) | |||
| { | |||
| case Entity::DRAWGROUP_BEGIN: | |||
| @@ -384,9 +408,16 @@ void TickerData::DrawThreadTick() | |||
| break; | |||
| } | |||
| //Stop as soon as required | |||
| for (int i = 0; i < data->m_list[g].Count() && !data->quit /* Stop as soon as required */; ++i) | |||
| { | |||
| //We're outside of the range of the current scene, on to the next | |||
| if (i >= data->m_scenes[g][scene_idx]) | |||
| { | |||
| //Scene::GetScene[scene_idx]->DisableDisplay(); //TODO | |||
| scene_idx++; | |||
| //Scene::GetScene[scene_idx]->EnableDisplay(); //TODO | |||
| } | |||
| Entity *e = data->m_list[g][i]; | |||
| if (!e->m_destroy) | |||
| @@ -397,7 +428,7 @@ void TickerData::DrawThreadTick() | |||
| e->GetName(), e); | |||
| e->m_tickstate = Entity::STATE_PRETICK_DRAW; | |||
| #endif | |||
| e->TickDraw(data->deltatime, *Scene::g_scene); | |||
| e->TickDraw(data->deltatime, *Scene::GetScene(scene_idx)); | |||
| #if !LOL_BUILD_RELEASE | |||
| if (e->m_tickstate != Entity::STATE_POSTTICK_DRAW) | |||
| Log::Error("entity %s [%p] missed super draw tick\n", | |||
| @@ -46,7 +46,7 @@ DebugRenderMode VideoData::render_mode = DebugRenderMode::Default; | |||
| void Video::Setup(ivec2 size) | |||
| { | |||
| g_renderer = new Renderer(size); | |||
| Scene::g_scene = new Scene(size); | |||
| Scene::AddNew(size); | |||
| /* Initialise reasonable scene default properties */ | |||
| SetDebugRenderMode(DebugRenderMode::Default); | |||
| @@ -94,8 +94,7 @@ DebugRenderMode Video::GetDebugRenderMode() | |||
| void Video::Destroy() | |||
| { | |||
| delete Scene::g_scene; | |||
| Scene::g_scene = nullptr; | |||
| Scene::DestroyAll(); | |||
| delete g_renderer; | |||
| g_renderer = nullptr; | |||