@@ -757,24 +757,18 @@ Global | |||||
{81C83B42-D00A-4FA3-9A3D-80F9D46524BF}.Release|x64.ActiveCfg = Release|x64 | {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|x64.Build.0 = Release|x64 | ||||
{81C83B42-D00A-4FA3-9A3D-80F9D46524BF}.Release|Xbox 360.ActiveCfg = Release|Win32 | {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.ActiveCfg = Debug|Win32 | ||||
{B9A255A0-2B92-4801-AF6C-354535A6E105}.Debug|Win32.Build.0 = 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.ActiveCfg = Debug|x64 | ||||
{B9A255A0-2B92-4801-AF6C-354535A6E105}.Debug|x64.Build.0 = 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.ActiveCfg = Release|Win32 | ||||
{B9A255A0-2B92-4801-AF6C-354535A6E105}.Release|Win32.Build.0 = 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.ActiveCfg = Release|x64 | ||||
{B9A255A0-2B92-4801-AF6C-354535A6E105}.Release|x64.Build.0 = 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 | EndGlobalSection | ||||
GlobalSection(SolutionProperties) = preSolution | GlobalSection(SolutionProperties) = preSolution | ||||
HideSolutionNode = FALSE | HideSolutionNode = FALSE | ||||
@@ -41,6 +41,7 @@ struct InitState | |||||
class Entity | class Entity | ||||
{ | { | ||||
friend class Scene; | |||||
friend class Ticker; | friend class Ticker; | ||||
friend class TickerData; | friend class TickerData; | ||||
friend class Dict; | friend class Dict; | ||||
@@ -146,6 +147,7 @@ private: | |||||
private: | private: | ||||
int m_ref, m_autorelease, m_destroy; | int m_ref, m_autorelease, m_destroy; | ||||
uint64_t m_scene_mask = 0; | |||||
}; | }; | ||||
} /* namespace lol */ | } /* namespace lol */ | ||||
@@ -253,7 +253,7 @@ void NaClInputData::Tick(float seconds) | |||||
//---- | //---- | ||||
void NaClInputData::InitViewportSize() | void NaClInputData::InitViewportSize() | ||||
{ | { | ||||
if (g_scene) | |||||
if (g_scenes.count()) | |||||
{ | { | ||||
m_app = vec2(Video::GetSize()); | m_app = vec2(Video::GetSize()); | ||||
//Dunno if its the good idea. | //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 | * A quick and dirty Tile structure for 2D blits | ||||
@@ -55,8 +55,25 @@ class SceneData | |||||
friend class Scene; | friend class Scene; | ||||
private: | 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 */ | /* New scenegraph */ | ||||
array<Primitive*> m_primitives; | 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> */ | /* Old API <P0, P1, COLOR, TIME, MASK> */ | ||||
float m_new_line_time; | float m_new_line_time; | ||||
@@ -81,6 +98,7 @@ private: | |||||
Camera *m_default_cam; | Camera *m_default_cam; | ||||
array<Camera *> m_camera_stack; | array<Camera *> m_camera_stack; | ||||
}; | }; | ||||
uint64_t SceneData::m_used_id = 1; | |||||
/* | /* | ||||
* Public Scene class | * Public Scene class | ||||
@@ -127,24 +145,64 @@ Scene::~Scene() | |||||
delete data; | 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) | 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) | 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() | 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); | 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) | void Scene::AddTile(TileSet *tileset, int id, vec3 pos, int o, vec2 scale, float angle) | ||||
{ | { | ||||
@@ -42,25 +42,49 @@ public: | |||||
private: | private: | ||||
}; | }; | ||||
class PrimitiveSettings | |||||
{ | |||||
friend class Scene; | |||||
public: | |||||
PrimitiveSettings() { } | |||||
virtual ~PrimitiveSettings() { } | |||||
virtual void ApplyTo(Primitive* primitive) const { } | |||||
private: | |||||
}; | |||||
//----------------------------------------------------------------------------- | |||||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
class Scene | class Scene | ||||
{ | { | ||||
friend class Video; | friend class Video; | ||||
friend class TickerData; //TODO: Smells shitty | |||||
private: | private: | ||||
static Scene *g_scene; | |||||
static array<Scene*> g_scenes; | |||||
Scene(ivec2 size); | Scene(ivec2 size); | ||||
~Scene(); | ~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 GetScene(Scene*& scene); | ||||
static bool GetSceneData(SceneData*& data); | static bool GetSceneData(SceneData*& data); | ||||
public: | public: | ||||
static bool IsReady(); | 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: | private: | ||||
static int PushCamera(Scene* scene, Camera *cam); | static int PushCamera(Scene* scene, Camera *cam); | ||||
static void PopCamera(Scene* scene, Camera *cam); | static void PopCamera(Scene* scene, Camera *cam); | ||||
@@ -74,6 +98,7 @@ public: | |||||
/* New scenegraph */ | /* New scenegraph */ | ||||
void AddPrimitive(Mesh const &mesh, mat4 const &matrix); | void AddPrimitive(Mesh const &mesh, mat4 const &matrix); | ||||
void AddPrimitive(Primitive* primitive); | void AddPrimitive(Primitive* primitive); | ||||
void AddPrimitive(Entity* entity, Primitive* primitive); | |||||
/* FIXME: this should be deprecated -- it doesn't really match | /* FIXME: this should be deprecated -- it doesn't really match | ||||
* the architecture we want to build */ | * the architecture we want to build */ | ||||
@@ -57,7 +57,8 @@ public: | |||||
private: | private: | ||||
/* Entity management */ | /* Entity management */ | ||||
array<Entity *> m_todolist, m_autolist; | 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; | ptrdiff_t nentities; | ||||
/* Fixed framerate management */ | /* Fixed framerate management */ | ||||
@@ -328,10 +329,32 @@ void TickerData::GameThreadTick() | |||||
{ | { | ||||
Entity *e = data->m_todolist.Last(); | 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) | 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 | // Initialize the entity | ||||
e->InitGame(); | e->InitGame(); | ||||
@@ -340,10 +363,9 @@ void TickerData::GameThreadTick() | |||||
/* Tick objects for the game loop */ | /* 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 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]; | Entity *e = data->m_list[g][i]; | ||||
if (!e->m_destroy) | if (!e->m_destroy) | ||||
{ | { | ||||
#if !LOL_BUILD_RELEASE | #if !LOL_BUILD_RELEASE | ||||
@@ -374,6 +396,8 @@ void TickerData::DrawThreadTick() | |||||
/* Tick objects for the draw loop */ | /* Tick objects for the draw loop */ | ||||
for (int g = Entity::DRAWGROUP_BEGIN; g < Entity::DRAWGROUP_END && !data->quit /* Stop as soon as required */; ++g) | 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) | switch (g) | ||||
{ | { | ||||
case Entity::DRAWGROUP_BEGIN: | case Entity::DRAWGROUP_BEGIN: | ||||
@@ -384,9 +408,16 @@ void TickerData::DrawThreadTick() | |||||
break; | break; | ||||
} | } | ||||
//Stop as soon as required | |||||
for (int i = 0; i < data->m_list[g].Count() && !data->quit /* Stop as soon as required */; ++i) | 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]; | Entity *e = data->m_list[g][i]; | ||||
if (!e->m_destroy) | if (!e->m_destroy) | ||||
@@ -397,7 +428,7 @@ void TickerData::DrawThreadTick() | |||||
e->GetName(), e); | e->GetName(), e); | ||||
e->m_tickstate = Entity::STATE_PRETICK_DRAW; | e->m_tickstate = Entity::STATE_PRETICK_DRAW; | ||||
#endif | #endif | ||||
e->TickDraw(data->deltatime, *Scene::g_scene); | |||||
e->TickDraw(data->deltatime, *Scene::GetScene(scene_idx)); | |||||
#if !LOL_BUILD_RELEASE | #if !LOL_BUILD_RELEASE | ||||
if (e->m_tickstate != Entity::STATE_POSTTICK_DRAW) | if (e->m_tickstate != Entity::STATE_POSTTICK_DRAW) | ||||
Log::Error("entity %s [%p] missed super draw tick\n", | 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) | void Video::Setup(ivec2 size) | ||||
{ | { | ||||
g_renderer = new Renderer(size); | g_renderer = new Renderer(size); | ||||
Scene::g_scene = new Scene(size); | |||||
Scene::AddNew(size); | |||||
/* Initialise reasonable scene default properties */ | /* Initialise reasonable scene default properties */ | ||||
SetDebugRenderMode(DebugRenderMode::Default); | SetDebugRenderMode(DebugRenderMode::Default); | ||||
@@ -94,8 +94,7 @@ DebugRenderMode Video::GetDebugRenderMode() | |||||
void Video::Destroy() | void Video::Destroy() | ||||
{ | { | ||||
delete Scene::g_scene; | |||||
Scene::g_scene = nullptr; | |||||
Scene::DestroyAll(); | |||||
delete g_renderer; | delete g_renderer; | ||||
g_renderer = nullptr; | g_renderer = nullptr; | ||||